mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-15 04:27:20 +03:00
feat(desktop): refresh question composer (#54822)
Co-authored-by: LukeParkerDev <10430890+Hona@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
2a593c0d1b
commit
3ec856b6c2
@@ -1,19 +1,187 @@
|
||||
import { expect, story } from "../../storybook/playwright/story"
|
||||
|
||||
story("shows question navigation shortcuts", async ({ mount, page }) => {
|
||||
const component = await mount("app-current-session-surface--question-request")
|
||||
const shortcut = await page.evaluate(() => (/Mac|iPhone|iPad|iPod/.test(navigator.platform) ? "⌘⏎" : "Ctrl+⏎"))
|
||||
const next = component.getByRole("button", { name: "Next", exact: true })
|
||||
await expect(next.locator('[data-slot="question-submit-shortcut"]')).toHaveText(shortcut)
|
||||
story("resizes the dock to fit different answer counts", async ({ mount }) => {
|
||||
const component = await mount("app-current-session-surface--question-answer-counts")
|
||||
const question = component.locator('[data-component="dock-prompt"][data-kind="question"]')
|
||||
const next = question.getByRole("button", { name: "Next", exact: true })
|
||||
await expect(question.getByRole("radio", { name: /Focused/ })).toBeFocused()
|
||||
await expect(next).toBeEnabled()
|
||||
|
||||
const height = () => question.evaluate((element) => element.getBoundingClientRect().height)
|
||||
const initial = await height()
|
||||
await next.click()
|
||||
await expect(component.getByRole("button", { name: "Submit", exact: true })).toContainText(shortcut)
|
||||
await expect.poll(height).toBeGreaterThan(initial)
|
||||
await expect(question.getByRole("checkbox", { name: "Diagnostics", exact: true })).toBeVisible()
|
||||
|
||||
const expanded = await height()
|
||||
const back = question.getByRole("button", { name: "Back", exact: true })
|
||||
await expect(back).toBeEnabled()
|
||||
await back.click()
|
||||
await expect.poll(height).toBeLessThan(expanded)
|
||||
await expect(question.getByRole("radio", { name: /Focused/ })).toBeVisible()
|
||||
})
|
||||
|
||||
story("selects single answers and toggles multiple answers with number keys", async ({ mount }) => {
|
||||
const component = await mount("app-current-session-surface--question-request")
|
||||
const question = component.locator('[data-component="dock-prompt"][data-kind="question"]')
|
||||
const focused = question.getByRole("radio", { name: /Focused/ })
|
||||
const wide = question.getByRole("radio", { name: /Wide/ })
|
||||
const customRadio = question.getByRole("radio", { name: "Type your own answer…", exact: true })
|
||||
const input = question.getByRole("textbox", { name: "Type your own answer…", exact: true })
|
||||
const next = question.getByRole("button", { name: "Next", exact: true })
|
||||
await expect(focused).toBeFocused()
|
||||
|
||||
await focused.press("2")
|
||||
await expect(wide).toBeChecked()
|
||||
await expect(focused).not.toBeChecked()
|
||||
await expect(wide).toBeFocused()
|
||||
await next.press("1")
|
||||
await expect(focused).toBeChecked()
|
||||
await expect(wide).not.toBeChecked()
|
||||
await focused.press("3")
|
||||
await expect(customRadio).toBeChecked()
|
||||
await expect(input).toBeFocused()
|
||||
await expect(focused).not.toBeChecked()
|
||||
await expect(wide).not.toBeChecked()
|
||||
await input.press("Enter")
|
||||
await expect(customRadio).toBeFocused()
|
||||
await customRadio.press("2")
|
||||
await expect(wide).toBeChecked()
|
||||
await expect(customRadio).not.toBeChecked()
|
||||
|
||||
await next.click()
|
||||
const files = question.getByRole("checkbox", { name: "Changed files", exact: true })
|
||||
const terminal = question.getByRole("checkbox", { name: "Terminal", exact: true })
|
||||
const customCheckbox = question.getByRole("checkbox", { name: "Type your own answer…", exact: true })
|
||||
await expect(files).toBeFocused()
|
||||
await files.press("1")
|
||||
await expect(files).toBeChecked()
|
||||
await files.press("2")
|
||||
await expect(terminal).toBeChecked()
|
||||
await expect(files).toBeChecked()
|
||||
await terminal.press("2")
|
||||
await expect(terminal).not.toBeChecked()
|
||||
await expect(files).toBeChecked()
|
||||
|
||||
await terminal.press("4")
|
||||
await expect(customCheckbox).toBeChecked()
|
||||
await expect(input).toBeFocused()
|
||||
await expect(files).toBeChecked()
|
||||
await expect(terminal).not.toBeChecked()
|
||||
await input.press("Enter")
|
||||
await expect(customCheckbox).toBeFocused()
|
||||
await customCheckbox.press("4")
|
||||
await expect(customCheckbox).not.toBeChecked()
|
||||
await expect(files).toBeChecked()
|
||||
await expect(terminal).not.toBeChecked()
|
||||
})
|
||||
|
||||
story("ignores modified, out-of-range, and repeated number shortcuts", async ({ mount, page }) => {
|
||||
const component = await mount("app-current-session-surface--question-request")
|
||||
const question = component.locator('[data-component="dock-prompt"][data-kind="question"]')
|
||||
const focused = question.getByRole("radio", { name: /Focused/ })
|
||||
const wide = question.getByRole("radio", { name: /Wide/ })
|
||||
await expect(focused).toBeFocused()
|
||||
await focused.press("1")
|
||||
await focused.press("9")
|
||||
await focused.press("Alt+2")
|
||||
await expect(focused).toBeChecked()
|
||||
await expect(wide).not.toBeChecked()
|
||||
|
||||
await question.getByRole("button", { name: "Next", exact: true }).click()
|
||||
const terminal = question.getByRole("checkbox", { name: "Terminal", exact: true })
|
||||
await expect(question.getByRole("checkbox", { name: "Changed files", exact: true })).toBeFocused()
|
||||
await page.keyboard.down("2")
|
||||
await expect(terminal).toBeChecked()
|
||||
await page.keyboard.down("2")
|
||||
await expect(terminal).toBeChecked()
|
||||
await page.keyboard.up("2")
|
||||
})
|
||||
|
||||
story("types digits into the custom answer without selecting numbered options", async ({ mount }) => {
|
||||
const component = await mount("app-current-session-surface--question-request")
|
||||
const question = component.locator('[data-component="dock-prompt"][data-kind="question"]')
|
||||
const focused = question.getByRole("radio", { name: /Focused/ })
|
||||
const custom = question.getByRole("radio", { name: "Type your own answer…", exact: true })
|
||||
const input = question.getByRole("textbox", { name: "Type your own answer…", exact: true })
|
||||
await expect(focused).toBeFocused()
|
||||
await focused.press("3")
|
||||
await expect(input).toBeFocused()
|
||||
await input.press("1")
|
||||
await input.press("2")
|
||||
await input.press("3")
|
||||
await expect(input).toHaveValue("123")
|
||||
await expect(custom).toBeChecked()
|
||||
await expect(focused).not.toBeChecked()
|
||||
await expect(question.getByRole("radio", { name: /Wide/ })).not.toBeChecked()
|
||||
})
|
||||
|
||||
story("shows question navigation shortcuts in buttons and tooltips", async ({ mount, page }) => {
|
||||
const component = await mount("app-current-session-surface--question-request")
|
||||
const mac = await page.evaluate(() => /Mac|iPhone|iPad|iPod/.test(navigator.platform))
|
||||
const shortcut = mac ? "⌘⏎" : "Ctrl+⏎"
|
||||
const next = component.getByRole("button", { name: "Next", exact: true })
|
||||
await expect(next.locator('[data-slot="question-submit-shortcut"]')).toBeVisible()
|
||||
await expect(next.locator('[data-slot="question-submit-shortcut"]')).toHaveText(shortcut)
|
||||
await expect(next).toHaveAttribute("aria-keyshortcuts", "Meta+Enter Control+Enter")
|
||||
await next.hover()
|
||||
await expect(page.getByRole("tooltip")).toContainText("Next")
|
||||
await expect(page.getByRole("tooltip")).toContainText(shortcut)
|
||||
await next.press(mac ? "Meta+Enter" : "Control+Enter")
|
||||
const submit = component.getByRole("button", { name: "Submit", exact: true })
|
||||
await expect(submit.locator('[data-slot="question-submit-shortcut"]')).toBeVisible()
|
||||
await expect(submit.locator('[data-slot="question-submit-shortcut"]')).toHaveText(shortcut)
|
||||
await expect(submit).toHaveAttribute("aria-keyshortcuts", "Meta+Enter Control+Enter")
|
||||
await submit.hover()
|
||||
await expect(page.getByRole("tooltip")).toContainText("Submit")
|
||||
await expect(page.getByRole("tooltip")).toContainText(shortcut)
|
||||
const back = component.getByRole("button", { name: "Back", exact: true })
|
||||
const backShortcut = await page.evaluate(() => (/Mac|iPhone|iPad|iPod/.test(navigator.platform) ? "⌘[" : "Alt+←"))
|
||||
await expect(back).toHaveText("Back")
|
||||
await expect(back).toHaveAttribute("aria-keyshortcuts", mac ? "Meta+[" : "Alt+ArrowLeft")
|
||||
await back.hover()
|
||||
await expect(page.getByRole("tooltip")).toContainText(backShortcut)
|
||||
await page.keyboard.press(
|
||||
await page.evaluate(() => (/Mac|iPhone|iPad|iPod/.test(navigator.platform) ? "Meta+[" : "Alt+ArrowLeft")),
|
||||
)
|
||||
await expect(page.getByRole("tooltip")).toContainText(mac ? "⌘[" : "Alt+←")
|
||||
await back.press(mac ? "Meta+[" : "Alt+ArrowLeft")
|
||||
await expect(next).toBeVisible()
|
||||
})
|
||||
|
||||
story("keeps the custom answer input and dock geometry stable while editing", async ({ mount }) => {
|
||||
const component = await mount("app-current-session-surface--question-request")
|
||||
const question = component.locator('[data-component="dock-prompt"][data-kind="question"]')
|
||||
const row = question.locator('[data-slot="question-option"][data-custom="true"]')
|
||||
const input = question.getByRole("textbox", { name: "Type your own answer…", exact: true })
|
||||
const toggle = question.getByRole("radio", { name: "Type your own answer…", exact: true })
|
||||
await expect(question.getByRole("radio", { name: /Focused/ })).toBeFocused()
|
||||
await expect(input).toBeEditable()
|
||||
await expect(input).toHaveValue("")
|
||||
const node = await input.evaluateHandle((element) => element)
|
||||
const height = () => question.evaluate((element) => element.getBoundingClientRect().height)
|
||||
const initial = await height()
|
||||
const draft = "A custom answer long enough to wrap if the editor becomes multiline instead of staying single-line"
|
||||
|
||||
const predefined = question.getByRole("radio", { name: /Focused/ })
|
||||
await predefined.click()
|
||||
await input.focus()
|
||||
await expect(input).toBeFocused()
|
||||
await expect(predefined).toBeChecked()
|
||||
await expect(toggle).not.toBeChecked()
|
||||
await row.click({ position: { x: 4, y: 4 } })
|
||||
await expect(toggle).toBeChecked()
|
||||
await expect(input).toBeFocused()
|
||||
await expect(input).toHaveValue("")
|
||||
await expect(predefined).not.toBeChecked()
|
||||
await input.fill(draft)
|
||||
await expect(input).toHaveValue(draft)
|
||||
await expect(toggle).toBeChecked()
|
||||
await expect(predefined).not.toBeChecked()
|
||||
await expect.poll(height).toBe(initial)
|
||||
await input.press("Enter")
|
||||
await expect(toggle).toBeFocused()
|
||||
await expect(input).toHaveValue(draft)
|
||||
await row.click({ position: { x: 30, y: 20 } })
|
||||
await expect(input).toBeFocused()
|
||||
await expect(input).toHaveValue(draft)
|
||||
await expect
|
||||
.poll(() => input.evaluate((element, original) => element === original && original.isConnected, node))
|
||||
.toBe(true)
|
||||
await node.dispose()
|
||||
})
|
||||
|
||||
@@ -83,6 +83,93 @@ test("shows a pending question dock", async ({ page }) => {
|
||||
expect((await reply).postDataJSON()).toEqual({ answer: { q0: "minimal" } })
|
||||
})
|
||||
|
||||
test("replies with predefined choices and the edited custom multiselect answer", async ({ page }) => {
|
||||
await mockServer(page, {
|
||||
forms: [
|
||||
{
|
||||
id: "frm_question_multiselect",
|
||||
sessionID,
|
||||
title: "Questions",
|
||||
metadata: { kind: "question" },
|
||||
fields: [
|
||||
{
|
||||
key: "q0",
|
||||
type: "multiselect",
|
||||
title: "Include",
|
||||
description: "Which supporting surfaces should remain visible?",
|
||||
options: [
|
||||
{ value: "files", label: "Changed files" },
|
||||
{ value: "terminal", label: "Terminal" },
|
||||
],
|
||||
custom: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
await page.goto(sessionHref(sessionID))
|
||||
await expectSessionTitle(page, title)
|
||||
const question = page.locator('[data-component="dock-prompt"][data-kind="question"]')
|
||||
const files = question.getByRole("checkbox", { name: "Changed files", exact: true })
|
||||
const terminal = question.getByRole("checkbox", { name: "Terminal", exact: true })
|
||||
const custom = question.getByRole("checkbox", { name: "Type your own answer…", exact: true })
|
||||
const input = question.getByRole("textbox", { name: "Type your own answer…", exact: true })
|
||||
const cancellations: string[] = []
|
||||
page.on("request", (request) => {
|
||||
if (
|
||||
request.method() === "DELETE" &&
|
||||
new URL(request.url()).pathname === `/api/session/${sessionID}/form/frm_question_multiselect`
|
||||
)
|
||||
cancellations.push(request.url())
|
||||
})
|
||||
|
||||
await expect(files).not.toBeChecked()
|
||||
await files.click()
|
||||
await input.fill("Original custom answer")
|
||||
await expect(custom).toBeChecked()
|
||||
await expect(files).toBeChecked()
|
||||
await terminal.click()
|
||||
await expect(terminal).toBeChecked()
|
||||
await expect(custom).toBeChecked()
|
||||
await expect(files).toBeChecked()
|
||||
|
||||
await custom.click()
|
||||
await expect(custom).not.toBeChecked()
|
||||
await expect(input).toHaveValue("Original custom answer")
|
||||
await expect(files).toBeChecked()
|
||||
await expect(terminal).toBeChecked()
|
||||
await input.focus()
|
||||
await expect(custom).not.toBeChecked()
|
||||
await expect(files).toBeChecked()
|
||||
await expect(terminal).toBeChecked()
|
||||
await custom.click()
|
||||
await expect(custom).toBeChecked()
|
||||
await expect(input).toHaveValue("Original custom answer")
|
||||
await expect(files).toBeChecked()
|
||||
await expect(terminal).toBeChecked()
|
||||
|
||||
await input.fill("Updated custom answer")
|
||||
await input.press("Escape")
|
||||
await expect(input).not.toBeFocused()
|
||||
await expect(question.getByRole("button", { name: "Submit", exact: true })).toBeEnabled()
|
||||
await expect(input).toHaveValue("Updated custom answer")
|
||||
await expect(custom).toBeChecked()
|
||||
await expect(files).toBeChecked()
|
||||
await expect(terminal).toBeChecked()
|
||||
expect(cancellations).toEqual([])
|
||||
|
||||
const reply = page.waitForRequest(
|
||||
(request) =>
|
||||
request.method() === "POST" &&
|
||||
new URL(request.url()).pathname === `/api/session/${sessionID}/form/frm_question_multiselect/reply`,
|
||||
)
|
||||
|
||||
await question.getByRole("button", { name: "Submit", exact: true }).press("Control+Enter")
|
||||
expect((await reply).postDataJSON()).toEqual({ answer: { q0: ["files", "terminal", "Updated custom answer"] } })
|
||||
expect(cancellations).toEqual([])
|
||||
})
|
||||
|
||||
test("shows a pending permission dock", async ({ page }) => {
|
||||
const replies: { sessionID: string; permissionID: string; body: unknown }[] = []
|
||||
await mockServer(page, {
|
||||
|
||||
@@ -553,6 +553,7 @@ export const dict = {
|
||||
"session.messages.jumpToLatest": "Jump to latest",
|
||||
|
||||
"session.question.progress": "{{current}} of {{total}} questions",
|
||||
"session.question.title": "Question",
|
||||
"session.websearch.title": "Third-party web search",
|
||||
"session.websearch.description": "Select the search provider agents use to search the web",
|
||||
"session.websearch.provider": "Search provider",
|
||||
|
||||
@@ -6,6 +6,7 @@ import { IconButton } from "@opencode/ui/icon-button"
|
||||
import { Tooltip } from "@opencode/ui/tooltip"
|
||||
import { DockPrompt } from "@opencode/session-ui/dock-prompt"
|
||||
import { Icon } from "@opencode/ui/icon"
|
||||
import { TextInput } from "@opencode/ui/text-input"
|
||||
import { useSpring } from "@opencode/ui/motion-spring"
|
||||
import { showToast } from "@/shell/notifications/toast"
|
||||
import type { FormAnswer, FormInfo, FormMultiselectField, FormStringField } from "@opencode/client/promise"
|
||||
@@ -18,7 +19,7 @@ import { useCommand } from "@/shell/commands/command"
|
||||
|
||||
const cache = new Map<string, { tab: number; answers: string[][]; custom: string[]; customOn: boolean[] }>()
|
||||
|
||||
const IS_MAC = typeof navigator === "object" && /(Mac|iPod|iPhone|iPad)/.test(navigator.platform)
|
||||
const IS_MAC = /(Mac|iPod|iPhone|iPad)/.test(navigator.platform)
|
||||
|
||||
type QuestionField = FormStringField | FormMultiselectField
|
||||
|
||||
@@ -26,12 +27,12 @@ function questionField(field: FormInfo["fields"][number]): field is QuestionFiel
|
||||
return field.type === "string" || field.type === "multiselect"
|
||||
}
|
||||
|
||||
function Mark(props: { multi: boolean; picked: boolean; onClick?: (event: MouseEvent) => void }) {
|
||||
function Mark(props: { multi: boolean; picked: boolean }) {
|
||||
return (
|
||||
<span data-slot="question-option-check" aria-hidden="true" onClick={props.onClick}>
|
||||
<span data-slot="question-option-check" aria-hidden="true">
|
||||
<span data-slot="question-option-box" data-type={props.multi ? "checkbox" : "radio"} data-picked={props.picked}>
|
||||
<Show when={props.multi} fallback={<span data-slot="question-option-radio-dot" />}>
|
||||
<Icon name="check-small" size="small" />
|
||||
<Icon name="check" size="normal" />
|
||||
</Show>
|
||||
</span>
|
||||
</span>
|
||||
@@ -43,6 +44,7 @@ function Option(props: {
|
||||
picked: boolean
|
||||
label: string
|
||||
description?: string
|
||||
shortcut?: string
|
||||
disabled: boolean
|
||||
ref?: (el: HTMLButtonElement) => void
|
||||
onFocus?: VoidFunction
|
||||
@@ -56,15 +58,20 @@ function Option(props: {
|
||||
data-picked={props.picked}
|
||||
role={props.multi ? "checkbox" : "radio"}
|
||||
aria-checked={props.picked}
|
||||
aria-keyshortcuts={props.shortcut}
|
||||
disabled={props.disabled}
|
||||
onFocus={props.onFocus}
|
||||
onClick={props.onClick}
|
||||
>
|
||||
<Mark multi={props.multi} picked={props.picked} />
|
||||
<span data-slot="question-option-main">
|
||||
<span data-slot="option-label">{props.label}</span>
|
||||
<span data-slot="option-label">
|
||||
<bdi>{props.label}</bdi>
|
||||
</span>
|
||||
<Show when={props.description}>
|
||||
<span data-slot="option-description">{props.description}</span>
|
||||
<span data-slot="option-description">
|
||||
<bdi>{props.description}</bdi>
|
||||
</span>
|
||||
</Show>
|
||||
</span>
|
||||
</button>
|
||||
@@ -93,9 +100,9 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
|
||||
const [store, setStore] = createStore({
|
||||
tab: cached?.tab ?? 0,
|
||||
answers: cached?.answers ?? ([] as string[][]),
|
||||
custom: cached?.custom ?? ([] as string[]),
|
||||
customOn: cached?.customOn ?? ([] as boolean[]),
|
||||
answers: cached?.answers ?? [],
|
||||
custom: cached?.custom ?? [],
|
||||
customOn: cached?.customOn ?? [],
|
||||
editing: false,
|
||||
focus: 0,
|
||||
minimized: false,
|
||||
@@ -105,6 +112,7 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
let root: HTMLDivElement | undefined
|
||||
let optionsRef: HTMLDivElement | undefined
|
||||
let customRef: HTMLButtonElement | undefined
|
||||
let customInput: HTMLInputElement | undefined
|
||||
let optsRef: HTMLButtonElement[] = []
|
||||
let replied = false
|
||||
let focusFrame: number | undefined
|
||||
@@ -117,13 +125,13 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
const count = createMemo(() => options().length + 1)
|
||||
|
||||
const summary = createMemo(() => {
|
||||
if (total() === 1) return language.t("session.question.title")
|
||||
const n = Math.min(store.tab + 1, total())
|
||||
|
||||
return language.t("session.question.progress", { current: n, total: total() })
|
||||
})
|
||||
|
||||
const customLabel = () => language.t("ui.messagePart.option.typeOwnAnswer")
|
||||
const customPlaceholder = () => language.t("ui.question.custom.placeholder")
|
||||
const customLabel = () => language.t("ui.question.custom.answerPlaceholder")
|
||||
|
||||
const last = createMemo(() => store.tab >= total() - 1)
|
||||
const collapse = useSpring(() => (store.minimized ? 1 : 0), { visualDuration: 0.3, bounce: 0 })
|
||||
@@ -255,10 +263,7 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
})
|
||||
})
|
||||
|
||||
const fail = (err: unknown) => {
|
||||
const message = err instanceof Error ? err.message : String(err)
|
||||
showToast({ title: language.t("common.requestFailed"), description: message })
|
||||
}
|
||||
const fail = (err: Error) => showToast({ title: language.t("common.requestFailed"), description: err.message })
|
||||
|
||||
const replyMutation = useMutation(() => ({
|
||||
mutationFn: (answer: FormAnswer) =>
|
||||
@@ -274,7 +279,8 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
}))
|
||||
|
||||
const rejectMutation = useMutation(() => ({
|
||||
mutationFn: () => serverSDK.api.session.form.cancel({ sessionID: props.request.sessionID, formID: props.request.id }),
|
||||
mutationFn: () =>
|
||||
serverSDK.api.session.form.cancel({ sessionID: props.request.sessionID, formID: props.request.id }),
|
||||
onMutate: () => {
|
||||
props.onSubmit()
|
||||
},
|
||||
@@ -320,12 +326,9 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
|
||||
const picked = (answer: string) => store.answers[store.tab]?.includes(answer) ?? false
|
||||
|
||||
const pick = (answer: string, custom: boolean = false) => {
|
||||
const pick = (answer: string) => {
|
||||
setStore("answers", store.tab, [answer])
|
||||
|
||||
if (custom) setStore("custom", store.tab, answer)
|
||||
|
||||
if (!custom) setStore("customOn", store.tab, false)
|
||||
setStore("customOn", store.tab, false)
|
||||
setStore("editing", false)
|
||||
}
|
||||
|
||||
@@ -345,6 +348,7 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
setStore("customOn", store.tab, true)
|
||||
setStore("editing", true)
|
||||
customUpdate(input(), true)
|
||||
customInput?.focus()
|
||||
|
||||
return
|
||||
}
|
||||
@@ -355,6 +359,7 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
if (next) {
|
||||
setStore("editing", true)
|
||||
customUpdate(input(), true)
|
||||
customInput?.focus()
|
||||
|
||||
return
|
||||
}
|
||||
@@ -366,15 +371,6 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
focus(options().length)
|
||||
}
|
||||
|
||||
const customOpen = () => {
|
||||
if (sending()) return
|
||||
setStore("focus", options().length)
|
||||
|
||||
if (!on()) setStore("customOn", store.tab, true)
|
||||
setStore("editing", true)
|
||||
customUpdate(input(), true)
|
||||
}
|
||||
|
||||
const move = (step: number) => {
|
||||
if (store.editing || sending()) return
|
||||
focus(store.focus + step)
|
||||
@@ -417,10 +413,29 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
|
||||
if (store.editing) return
|
||||
|
||||
if (!(target instanceof HTMLElement)) return
|
||||
|
||||
if (event.altKey || event.ctrlKey || event.metaKey) return
|
||||
|
||||
if (/^[1-9]$/.test(event.key)) {
|
||||
if (event.repeat || event.isComposing || store.minimized || sending()) return
|
||||
const index = Number(event.key) - 1
|
||||
|
||||
if (index >= count()) return
|
||||
event.preventDefault()
|
||||
|
||||
if (index === options().length) {
|
||||
customToggle()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
selectOption(index)
|
||||
focus(index)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (!(target instanceof HTMLElement)) return
|
||||
|
||||
if (event.key === "ArrowDown" || event.key === "ArrowRight") {
|
||||
event.preventDefault()
|
||||
move(1)
|
||||
@@ -450,12 +465,6 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
const selectOption = (optIndex: number) => {
|
||||
if (sending()) return
|
||||
|
||||
if (optIndex === options().length) {
|
||||
customOpen()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const opt = options()[optIndex]
|
||||
|
||||
if (!opt) return
|
||||
@@ -476,24 +485,6 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
focus(options().length)
|
||||
}
|
||||
|
||||
const resizeInput = (el: HTMLTextAreaElement) => {
|
||||
el.style.height = "0px"
|
||||
el.style.height = `${el.scrollHeight}px`
|
||||
}
|
||||
|
||||
const focusCustom = (el: HTMLTextAreaElement) => {
|
||||
setTimeout(() => {
|
||||
el.focus()
|
||||
resizeInput(el)
|
||||
}, 0)
|
||||
}
|
||||
|
||||
const toggleCustomMark = (event: MouseEvent) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
customToggle()
|
||||
}
|
||||
|
||||
const next = () => {
|
||||
if (sending()) return
|
||||
|
||||
@@ -505,29 +496,23 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
return
|
||||
}
|
||||
|
||||
const tab = store.tab + 1
|
||||
setStore("tab", tab)
|
||||
setStore("editing", false)
|
||||
|
||||
if (!store.minimized) focus(pickFocus(tab))
|
||||
jump(store.tab + 1)
|
||||
}
|
||||
|
||||
const back = () => {
|
||||
if (sending()) return
|
||||
|
||||
if (store.tab <= 0) return
|
||||
const tab = store.tab - 1
|
||||
setStore("tab", tab)
|
||||
setStore("editing", false)
|
||||
|
||||
if (!store.minimized) focus(pickFocus(tab))
|
||||
jump(store.tab - 1)
|
||||
}
|
||||
|
||||
const jump = (tab: number) => {
|
||||
if (sending()) return
|
||||
if (sending() || tab === store.tab) return
|
||||
setStore("tab", tab)
|
||||
setStore("editing", false)
|
||||
|
||||
if (optionsRef) setStore("optionsHeight", optionsRef.scrollHeight)
|
||||
|
||||
if (!store.minimized) focus(pickFocus(tab))
|
||||
}
|
||||
|
||||
@@ -564,33 +549,57 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
onKeyDown={nav}
|
||||
header={
|
||||
<>
|
||||
<div data-slot="question-header-title">{summary()}</div>
|
||||
<div data-slot="question-header-actions">
|
||||
<Show when={total() > 1}>
|
||||
<div data-slot="question-progress">
|
||||
<For each={questions()}>
|
||||
{(_, i) => (
|
||||
<button
|
||||
type="button"
|
||||
data-slot="question-progress-segment"
|
||||
data-active={i() === store.tab}
|
||||
data-answered={answered(i())}
|
||||
disabled={sending()}
|
||||
onClick={() => jump(i())}
|
||||
aria-label={language.t("ui.tool.questions.numbered", { number: i() + 1 })}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
<div data-slot="question-header-top">
|
||||
<div data-slot="question-header-title">
|
||||
<bdi>{summary()}</bdi>
|
||||
</div>
|
||||
<div data-slot="question-header-actions">
|
||||
<Show when={total() > 1}>
|
||||
<div data-slot="question-progress">
|
||||
<For each={questions()}>
|
||||
{(_, i) => (
|
||||
<button
|
||||
type="button"
|
||||
data-slot="question-progress-segment"
|
||||
data-active={i() === store.tab}
|
||||
data-answered={answered(i())}
|
||||
disabled={sending()}
|
||||
onClick={() => jump(i())}
|
||||
aria-label={language.t("ui.tool.questions.numbered", { number: i() + 1 })}
|
||||
aria-current={i() === store.tab ? "step" : undefined}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</Show>
|
||||
<IconButton
|
||||
icon={<Icon name="outline-chevron-down" size="normal" />}
|
||||
variant="ghost"
|
||||
size="large"
|
||||
disabled={sending()}
|
||||
style={{ transform: `rotate(${hidden() * 180}deg)` }}
|
||||
onClick={store.minimized ? restore : minimize}
|
||||
aria-label={language.t(store.minimized ? "session.question.restore" : "session.question.minimize")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div data-slot="question-details">
|
||||
<div
|
||||
data-slot="question-text"
|
||||
style={{
|
||||
display: store.minimized ? "-webkit-box" : undefined,
|
||||
"-webkit-line-clamp": store.minimized ? "3" : undefined,
|
||||
"-webkit-box-orient": store.minimized ? "vertical" : undefined,
|
||||
overflow: store.minimized ? "hidden" : undefined,
|
||||
}}
|
||||
>
|
||||
<bdi>{question()?.question}</bdi>
|
||||
</div>
|
||||
<Show when={!store.minimized}>
|
||||
<div data-slot="question-hint">
|
||||
{language.t(multi() ? "ui.question.multiHint" : "ui.question.singleHint")}
|
||||
</div>
|
||||
</Show>
|
||||
<IconButton
|
||||
icon={<Icon name="chevron-down" size="small" />}
|
||||
variant="ghost"
|
||||
disabled={sending()}
|
||||
style={{ transform: `rotate(${hidden() * 180}deg)` }}
|
||||
onClick={store.minimized ? restore : minimize}
|
||||
aria-label={language.t(store.minimized ? "session.question.restore" : "session.question.minimize")}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
@@ -606,7 +615,7 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
value={
|
||||
<>
|
||||
{language.t("ui.common.back")}
|
||||
<span class="opacity-60">{backShortcut()}</span>
|
||||
<span style={{ opacity: 0.6 }}>{backShortcut()}</span>
|
||||
</>
|
||||
}
|
||||
>
|
||||
@@ -621,41 +630,38 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Show>
|
||||
<Button
|
||||
variant={last() ? "submit" : "neutral"}
|
||||
size="large"
|
||||
disabled={sending()}
|
||||
onClick={next}
|
||||
aria-keyshortcuts="Meta+Enter Control+Enter"
|
||||
<Tooltip
|
||||
placement="top"
|
||||
value={
|
||||
<>
|
||||
{language.t(last() ? "ui.common.submit" : "ui.common.next")}
|
||||
<span style={{ opacity: 0.6 }}>{submitShortcut()}</span>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{last() ? language.t("ui.common.submit") : language.t("ui.common.next")}
|
||||
<span data-slot="question-submit-shortcut" aria-hidden="true" class="text-11-medium opacity-60">
|
||||
{submitShortcut()}
|
||||
</span>
|
||||
</Button>
|
||||
<Button
|
||||
variant={last() ? "submit" : "neutral"}
|
||||
size="large"
|
||||
disabled={sending()}
|
||||
onClick={next}
|
||||
aria-keyshortcuts="Meta+Enter Control+Enter"
|
||||
>
|
||||
{language.t(last() ? "ui.common.submit" : "ui.common.next")}
|
||||
<span data-slot="question-submit-shortcut" aria-hidden="true">
|
||||
{submitShortcut()}
|
||||
</span>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<div
|
||||
data-slot="question-text"
|
||||
style={{
|
||||
display: store.minimized ? "-webkit-box" : undefined,
|
||||
"-webkit-line-clamp": store.minimized ? "3" : undefined,
|
||||
"-webkit-box-orient": store.minimized ? "vertical" : undefined,
|
||||
overflow: store.minimized ? "hidden" : undefined,
|
||||
}}
|
||||
>
|
||||
{question()?.question}
|
||||
</div>
|
||||
<Show when={!store.minimized}>
|
||||
<Show when={multi()} fallback={<div data-slot="question-hint">{language.t("ui.question.singleHint")}</div>}>
|
||||
<div data-slot="question-hint">{language.t("ui.question.multiHint")}</div>
|
||||
</Show>
|
||||
</Show>
|
||||
<div
|
||||
ref={(el) => (optionsRef = el)}
|
||||
data-slot="question-options"
|
||||
role={multi() ? "group" : "radiogroup"}
|
||||
aria-label={question()?.question}
|
||||
inert={store.minimized}
|
||||
aria-hidden={store.minimized || optionsOff() ? "true" : undefined}
|
||||
classList={{ "pointer-events-none": hidden() > 0.1 }}
|
||||
style={{
|
||||
@@ -671,6 +677,7 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
picked={picked(opt.value)}
|
||||
label={opt.label}
|
||||
description={opt.description}
|
||||
shortcut={i() < 9 ? String(i() + 1) : undefined}
|
||||
disabled={sending()}
|
||||
ref={(el) => (optsRef[i()] = el)}
|
||||
onFocus={() => setStore("focus", i())}
|
||||
@@ -679,89 +686,75 @@ export const SessionQuestionDock: Component<{ request: FormInfo; onSubmit: () =>
|
||||
)}
|
||||
</For>
|
||||
|
||||
<Show
|
||||
when={store.editing}
|
||||
fallback={
|
||||
<button
|
||||
type="button"
|
||||
ref={customRef}
|
||||
data-slot="question-option"
|
||||
data-custom="true"
|
||||
data-picked={on()}
|
||||
role={multi() ? "checkbox" : "radio"}
|
||||
aria-checked={on()}
|
||||
disabled={sending()}
|
||||
onFocus={() => setStore("focus", options().length)}
|
||||
onClick={customOpen}
|
||||
>
|
||||
<Mark multi={multi()} picked={on()} onClick={toggleCustomMark} />
|
||||
<span data-slot="question-option-main">
|
||||
<span data-slot="option-label">{customLabel()}</span>
|
||||
<span data-slot="option-description" dir="auto">
|
||||
{input() || customPlaceholder()}
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
}
|
||||
<div
|
||||
data-slot="question-option"
|
||||
data-custom="true"
|
||||
data-picked={on()}
|
||||
data-editing={store.editing}
|
||||
data-disabled={sending()}
|
||||
onClick={(event) => {
|
||||
if (event.target !== event.currentTarget || sending()) return
|
||||
setStore("focus", options().length)
|
||||
setStore("customOn", store.tab, true)
|
||||
setStore("editing", true)
|
||||
customUpdate(input(), true)
|
||||
customInput?.focus()
|
||||
}}
|
||||
>
|
||||
<form
|
||||
data-slot="question-option"
|
||||
data-custom="true"
|
||||
data-picked={on()}
|
||||
<button
|
||||
type="button"
|
||||
ref={customRef}
|
||||
data-slot="question-custom-toggle"
|
||||
role={multi() ? "checkbox" : "radio"}
|
||||
aria-checked={on()}
|
||||
onMouseDown={(e) => {
|
||||
if (sending()) {
|
||||
aria-label={customLabel()}
|
||||
aria-keyshortcuts={count() <= 9 ? String(count()) : undefined}
|
||||
disabled={sending()}
|
||||
onFocus={() => setStore("focus", options().length)}
|
||||
onClick={customToggle}
|
||||
>
|
||||
<Mark multi={multi()} picked={on()} />
|
||||
</button>
|
||||
<TextInput
|
||||
ref={(el) => (customInput = el)}
|
||||
class="question-custom-field"
|
||||
dir="auto"
|
||||
aria-label={customLabel()}
|
||||
placeholder={customLabel()}
|
||||
value={input()}
|
||||
disabled={sending()}
|
||||
onFocus={() => {
|
||||
if (focusFrame !== undefined) cancelAnimationFrame(focusFrame)
|
||||
focusFrame = undefined
|
||||
setStore("focus", options().length)
|
||||
setStore("editing", true)
|
||||
}}
|
||||
onClick={() => {
|
||||
setStore("customOn", store.tab, true)
|
||||
customUpdate(input(), true)
|
||||
}}
|
||||
onBlur={() => setStore("editing", false)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Escape") {
|
||||
e.preventDefault()
|
||||
setStore("editing", false)
|
||||
focus(options().length)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (e.target instanceof HTMLTextAreaElement) return
|
||||
const input = e.currentTarget.querySelector('[data-slot="question-custom-input"]')
|
||||
if ((e.metaKey || e.ctrlKey) && !e.altKey) return
|
||||
|
||||
if (input instanceof HTMLTextAreaElement) input.focus()
|
||||
}}
|
||||
onSubmit={(e) => {
|
||||
if (e.key !== "Enter") return
|
||||
e.preventDefault()
|
||||
commitCustom()
|
||||
}}
|
||||
>
|
||||
<Mark multi={multi()} picked={on()} onClick={toggleCustomMark} />
|
||||
<span data-slot="question-option-main">
|
||||
<span data-slot="option-label">{customLabel()}</span>
|
||||
<textarea
|
||||
ref={focusCustom}
|
||||
data-slot="question-custom-input"
|
||||
dir="auto"
|
||||
placeholder={customPlaceholder()}
|
||||
value={input()}
|
||||
rows={1}
|
||||
disabled={sending()}
|
||||
style={{ "unicode-bidi": "plaintext", "text-align": "start" }}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Escape") {
|
||||
e.preventDefault()
|
||||
setStore("editing", false)
|
||||
focus(options().length)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if ((e.metaKey || e.ctrlKey) && !e.altKey) return
|
||||
|
||||
if (e.key !== "Enter" || e.shiftKey) return
|
||||
e.preventDefault()
|
||||
commitCustom()
|
||||
}}
|
||||
onInput={(e) => {
|
||||
customUpdate(e.currentTarget.value)
|
||||
resizeInput(e.currentTarget)
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
</form>
|
||||
</Show>
|
||||
onInput={(e) => {
|
||||
setStore("customOn", store.tab, true)
|
||||
customUpdate(e.currentTarget.value, true)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</DockPrompt>
|
||||
</div>
|
||||
|
||||
@@ -142,6 +142,29 @@ export const QuestionRequest = {
|
||||
),
|
||||
}
|
||||
|
||||
export const QuestionAnswerCounts = {
|
||||
render: () => (
|
||||
<SessionPreview
|
||||
title="Choose supporting surfaces"
|
||||
description={description}
|
||||
document={questionPendingDocument}
|
||||
request={{
|
||||
type: "question",
|
||||
value: {
|
||||
...activeQuestionRequest,
|
||||
fields: [
|
||||
activeQuestionRequest.fields[0],
|
||||
{
|
||||
...activeQuestionRequest.fields[1],
|
||||
options: [...activeQuestionRequest.fields[1].options, { value: "diagnostics", label: "Diagnostics" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
}}
|
||||
/>
|
||||
),
|
||||
}
|
||||
|
||||
export const WebSearchRequest = {
|
||||
render: () => (
|
||||
<SessionPreview
|
||||
|
||||
@@ -19,19 +19,29 @@ export const Question = {
|
||||
render: () => (
|
||||
<DockPrompt
|
||||
kind="question"
|
||||
header={<div class="text-13-medium text-text-strong">Session layout</div>}
|
||||
header={
|
||||
<>
|
||||
<div data-slot="question-header-top">
|
||||
<div data-slot="question-header-title">Question</div>
|
||||
</div>
|
||||
<div data-slot="question-details">
|
||||
<div data-slot="question-text">Which Session layout should I implement?</div>
|
||||
<div data-slot="question-hint">Select one answer</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
footer={
|
||||
<>
|
||||
<Button size="normal" variant="ghost">
|
||||
<Button size="large" variant="ghost">
|
||||
Dismiss
|
||||
</Button>
|
||||
<Button size="normal" variant="contrast">
|
||||
<Button size="large" variant="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<div class="text-13-regular text-text-base">Which Session layout should I implement?</div>
|
||||
<div data-slot="question-options" />
|
||||
</DockPrompt>
|
||||
),
|
||||
}
|
||||
|
||||
@@ -933,351 +933,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
[data-component="dock-prompt"][data-kind="question"] {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
min-height: 0;
|
||||
max-height: var(--question-prompt-max-height, 100dvh);
|
||||
|
||||
[data-slot="question-body"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
padding: 8px 8px 0;
|
||||
}
|
||||
|
||||
[data-slot="question-header"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
[data-slot="question-header-title"] {
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: 14px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: var(--line-height-large);
|
||||
color: var(--v2-text-text-base);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
[data-slot="question-header-actions"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
[data-slot="question-progress"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
[data-slot="question-progress-segment"] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
border-radius: 999px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
touch-action: manipulation;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
width: 16px;
|
||||
height: 2px;
|
||||
border-radius: 999px;
|
||||
background-color: var(--v2-icon-icon-muted);
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
&[data-active="true"]::after {
|
||||
background-color: var(--icon-strong-base);
|
||||
}
|
||||
|
||||
&[data-answered="true"]::after {
|
||||
background-color: var(--icon-interactive-base);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-content"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
[data-slot="question-text"] {
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: 14px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: var(--line-height-large);
|
||||
color: var(--v2-text-text-base);
|
||||
padding: 0 10px;
|
||||
flex-shrink: 0;
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
[data-slot="question-hint"] {
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: 13px;
|
||||
font-weight: var(--font-weight-regular);
|
||||
line-height: var(--line-height-large);
|
||||
color: var(--v2-text-text-muted);
|
||||
padding: 0 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
[data-slot="question-options"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
margin-top: 12px;
|
||||
padding: 1px 1px 16px;
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-option"] {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12px;
|
||||
padding: 8px 8px 8px 10px;
|
||||
background-color: var(--v2-background-bg-layer-01);
|
||||
border: 0.5px solid var(--v2-border-border-base);
|
||||
border-radius: 6px;
|
||||
box-shadow: none;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background-color 0.15s ease,
|
||||
border-color 0.15s ease,
|
||||
box-shadow 0.15s ease;
|
||||
|
||||
&:hover:not([data-picked="true"]) {
|
||||
background-color: var(--v2-background-bg-base);
|
||||
}
|
||||
|
||||
&[data-picked="true"] {
|
||||
background-color: var(--v2-state-bg-info);
|
||||
border-color: transparent;
|
||||
box-shadow: var(--shadow-xs-border-hover);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-option-check"] {
|
||||
display: inline-flex;
|
||||
transform: translateY(2px);
|
||||
}
|
||||
|
||||
[data-slot="question-option-box"] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 2px;
|
||||
border-radius: var(--radius-sm);
|
||||
border: 0.5px solid var(--v2-border-border-base);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
background-color: transparent;
|
||||
transition:
|
||||
background-color 0.15s ease,
|
||||
border-color 0.15s ease;
|
||||
|
||||
[data-slot="icon-svg"] {
|
||||
opacity: 0;
|
||||
color: var(--icon-base);
|
||||
}
|
||||
|
||||
&[data-type="radio"] {
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
[data-slot="question-option-radio-dot"] {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 999px;
|
||||
background-color: var(--v2-background-bg-layer-01);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&[data-picked="true"] {
|
||||
border-color: var(--icon-interactive-base);
|
||||
|
||||
[data-slot="icon-svg"] {
|
||||
opacity: 1;
|
||||
color: var(--icon-invert-base);
|
||||
}
|
||||
|
||||
&[data-type="checkbox"] {
|
||||
background-color: var(--icon-interactive-base);
|
||||
}
|
||||
|
||||
&[data-type="radio"] {
|
||||
background-color: var(--icon-interactive-base);
|
||||
[data-slot="question-option-radio-dot"] {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-option-main"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
[data-slot="option-label"] {
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: 14px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: var(--line-height-large);
|
||||
color: var(--v2-text-text-base);
|
||||
}
|
||||
|
||||
[data-slot="option-description"] {
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: 14px;
|
||||
font-weight: var(--font-weight-regular);
|
||||
line-height: var(--line-height-large);
|
||||
color: var(--v2-text-text-muted);
|
||||
min-width: 0;
|
||||
overflow-wrap: anywhere;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
[data-slot="question-custom"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
[data-slot="question-custom-input-wrap"] {
|
||||
padding-left: 36px;
|
||||
}
|
||||
|
||||
[data-slot="question-custom-input"] {
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: 14px;
|
||||
font-weight: var(--font-weight-regular);
|
||||
line-height: var(--line-height-large);
|
||||
color: var(--v2-text-text-muted);
|
||||
min-width: 0;
|
||||
cursor: text;
|
||||
resize: none;
|
||||
overflow: hidden;
|
||||
overflow-wrap: anywhere;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--v2-text-text-muted);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 0.5px solid var(--v2-border-border-focus);
|
||||
outline-offset: 2px;
|
||||
border-radius: var(--radius-xs);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-footer"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-shrink: 0;
|
||||
padding: 32px 8px 8px;
|
||||
margin-top: -24px;
|
||||
}
|
||||
|
||||
[data-slot="question-footer-actions"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
[data-component="question-minimized-dock"] {
|
||||
margin-bottom: 8px;
|
||||
|
||||
[data-slot="question-minimized-trigger"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
width: 100%;
|
||||
padding: 10px 12px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--v2-text-text-base);
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
touch-action: manipulation;
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
[data-slot="icon-svg"] {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-minimized-summary"] {
|
||||
flex: 1;
|
||||
font-family: var(--font-family-sans);
|
||||
font-size: 14px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
line-height: var(--line-height-large);
|
||||
color: var(--v2-text-text-base);
|
||||
}
|
||||
}
|
||||
|
||||
[data-component="question-answers"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -0,0 +1,439 @@
|
||||
[data-component="dock-prompt"][data-kind="question"] {
|
||||
--v2-question-answer-bg-selected: light-dark(#f5f8ff, #7698fd26);
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
min-block-size: 0;
|
||||
max-block-size: var(--question-prompt-max-height, 100dvh);
|
||||
font-family: var(--v2-font-family-sans);
|
||||
|
||||
[data-slot="question-body"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
flex: 1;
|
||||
min-block-size: 0;
|
||||
padding: 8px;
|
||||
background-color: var(--v2-background-bg-base);
|
||||
border-radius: 10px;
|
||||
box-shadow: var(--v2-elevation-raised);
|
||||
}
|
||||
|
||||
[data-slot="question-header"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
flex-shrink: 0;
|
||||
min-inline-size: 0;
|
||||
padding-inline: 4px;
|
||||
}
|
||||
|
||||
[data-slot="question-header-top"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
min-block-size: 28px;
|
||||
min-inline-size: 0;
|
||||
}
|
||||
|
||||
[data-slot="question-header-title"] {
|
||||
min-inline-size: 0;
|
||||
font-size: 13px;
|
||||
font-weight: 440;
|
||||
line-height: var(--line-height-base);
|
||||
color: var(--v2-text-text-muted);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
[data-slot="question-header-actions"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
|
||||
[data-component="icon-button-v2"] {
|
||||
flex-shrink: 0;
|
||||
color: var(--v2-icon-icon-muted);
|
||||
}
|
||||
|
||||
[data-slot="icon-svg"] {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-details"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
min-inline-size: 0;
|
||||
}
|
||||
|
||||
[data-slot="question-text"] {
|
||||
font-size: 13px;
|
||||
font-weight: 530;
|
||||
line-height: var(--line-height-base);
|
||||
color: var(--v2-text-text-base);
|
||||
overflow-wrap: anywhere;
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
[data-slot="question-hint"] {
|
||||
font-size: 11px;
|
||||
font-weight: 440;
|
||||
line-height: var(--line-height-tight);
|
||||
color: var(--v2-text-text-faint);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
[data-slot="question-progress"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
[data-slot="question-progress-segment"] {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
inline-size: 20px;
|
||||
block-size: 20px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
touch-action: manipulation;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
inline-size: 14px;
|
||||
block-size: 2px;
|
||||
flex-shrink: 0;
|
||||
background-color: var(--v2-background-bg-layer-04);
|
||||
}
|
||||
|
||||
&[data-answered="true"]::after {
|
||||
background-color: var(--v2-background-bg-accent);
|
||||
}
|
||||
|
||||
&[data-active="true"]::after {
|
||||
background-color: var(--v2-icon-icon-muted);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--v2-border-border-focus);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-content"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
min-block-size: 0;
|
||||
min-inline-size: 0;
|
||||
}
|
||||
|
||||
[data-slot="question-options"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
flex: 1 1 auto;
|
||||
min-block-size: 0;
|
||||
min-inline-size: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-option"] {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
box-sizing: border-box;
|
||||
inline-size: 100%;
|
||||
padding: 10px;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
background-color: var(--v2-background-bg-layer-01);
|
||||
box-shadow: inset 0 0 0 0.5px var(--v2-border-border-base);
|
||||
color: var(--v2-text-text-base);
|
||||
text-align: start;
|
||||
cursor: pointer;
|
||||
touch-action: manipulation;
|
||||
transition: background-color 150ms ease;
|
||||
|
||||
&[data-picked="true"] {
|
||||
background-image: linear-gradient(var(--v2-question-answer-bg-selected), var(--v2-question-answer-bg-selected));
|
||||
box-shadow: inset 0 0 0 0.5px var(--v2-border-border-focus);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--v2-border-border-focus);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&[data-disabled="true"] {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-option-check"] {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
inline-size: 16px;
|
||||
block-size: 20px;
|
||||
flex: 0 0 16px;
|
||||
}
|
||||
|
||||
[data-slot="question-option-box"] {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
inline-size: 16px;
|
||||
block-size: 16px;
|
||||
flex: 0 0 16px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
background: linear-gradient(180deg, var(--v2-alpha-light-6), var(--v2-alpha-light-0)), var(--v2-background-bg-base);
|
||||
box-shadow: inset 0 0 0 0.5px var(--v2-border-border-strong);
|
||||
|
||||
[data-slot="icon-svg"] {
|
||||
inline-size: 16px;
|
||||
block-size: 16px;
|
||||
flex: 0 0 16px;
|
||||
opacity: 0;
|
||||
color: var(--v2-icon-icon-contrast);
|
||||
}
|
||||
|
||||
&[data-type="radio"] {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
[data-slot="question-option-radio-dot"] {
|
||||
inline-size: 6px;
|
||||
block-size: 6px;
|
||||
flex: 0 0 6px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--v2-grey-300);
|
||||
box-shadow: var(--v2-elevation-elements);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&[data-picked="true"] {
|
||||
background:
|
||||
linear-gradient(180deg, var(--v2-alpha-light-20), var(--v2-alpha-light-0)), var(--v2-background-bg-accent);
|
||||
|
||||
[data-slot="icon-svg"],
|
||||
[data-slot="question-option-radio-dot"] {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&[data-type="radio"] {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-option-main"] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
min-inline-size: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
[data-slot="option-label"] {
|
||||
font-family: var(--v2-font-family-sans);
|
||||
font-size: 13px;
|
||||
font-weight: 530;
|
||||
line-height: var(--line-height-base);
|
||||
color: var(--v2-text-text-base);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
[data-slot="option-description"] {
|
||||
min-inline-size: 0;
|
||||
font-family: var(--v2-font-family-sans);
|
||||
font-size: 13px;
|
||||
font-weight: 440;
|
||||
line-height: var(--line-height-base);
|
||||
color: var(--v2-text-text-muted);
|
||||
overflow-wrap: anywhere;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
[data-slot="question-option"][data-custom="true"] {
|
||||
align-items: center;
|
||||
block-size: 40px;
|
||||
min-block-size: 40px;
|
||||
max-block-size: 40px;
|
||||
padding-block: 0;
|
||||
padding-inline: 10px;
|
||||
|
||||
&:not([data-editing="true"]) [data-slot="text-input-v2-input"] {
|
||||
font-weight: 530;
|
||||
}
|
||||
|
||||
&[data-editing="true"] .question-custom-field[data-component="text-input-v2"] {
|
||||
background:
|
||||
linear-gradient(180deg, var(--v2-alpha-light-2), var(--v2-alpha-light-0)), var(--v2-background-bg-base);
|
||||
box-shadow: inset 0 0 0 1px var(--v2-border-border-focus);
|
||||
|
||||
[data-slot="text-input-v2-input"] {
|
||||
padding-inline: 8px;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--v2-text-text-faint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-custom-toggle"] {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
inline-size: 16px;
|
||||
block-size: 20px;
|
||||
flex: 0 0 16px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
touch-action: manipulation;
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--v2-border-border-focus);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-option"] .question-custom-field[data-component="text-input-v2"] {
|
||||
flex: 1;
|
||||
inline-size: 100%;
|
||||
min-inline-size: 0;
|
||||
block-size: 28px;
|
||||
align-self: center;
|
||||
padding: 0;
|
||||
gap: 0;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
opacity: 1;
|
||||
transition: none;
|
||||
|
||||
[data-slot="text-input-v2-value"] {
|
||||
min-inline-size: 0;
|
||||
min-block-size: 0;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
[data-slot="text-input-v2-input"] {
|
||||
box-sizing: border-box;
|
||||
inline-size: 100%;
|
||||
min-inline-size: 0;
|
||||
block-size: 28px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
font-family: var(--v2-font-family-sans);
|
||||
font-size: 13px;
|
||||
font-weight: 440;
|
||||
line-height: var(--line-height-compact);
|
||||
color: var(--v2-text-text-base);
|
||||
text-align: start;
|
||||
cursor: text;
|
||||
|
||||
&::placeholder {
|
||||
color: var(--v2-text-text-base);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-footer"] {
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-shrink: 0;
|
||||
padding-block: 16px 8px;
|
||||
padding-inline: 12px;
|
||||
margin-block-start: -9px;
|
||||
border: 0.5px solid var(--v2-border-border-base);
|
||||
border-start-start-radius: 0;
|
||||
border-start-end-radius: 0;
|
||||
border-end-start-radius: 10px;
|
||||
border-end-end-radius: 10px;
|
||||
background-color: var(--v2-background-bg-layer-01);
|
||||
|
||||
> [data-component="button-v2"][data-variant="ghost"] {
|
||||
color: var(--v2-text-text-muted);
|
||||
}
|
||||
}
|
||||
|
||||
[data-slot="question-footer-actions"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
[data-slot="question-submit-shortcut"] {
|
||||
flex-shrink: 0;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
[data-slot="question-progress-segment"]:hover:not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
|
||||
[data-slot="question-option"]:hover:not(:disabled):not([data-disabled="true"]):not([data-picked="true"]) {
|
||||
background-color: var(--v2-background-bg-layer-02);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
[data-slot="question-option"],
|
||||
.question-custom-field[data-component="text-input-v2"] {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
@import "../components/markdown.css" layer(components);
|
||||
@import "../components/message-part.css" layer(components);
|
||||
@import "../components/message-nav.css" layer(components);
|
||||
@import "../components/question-prompt.css" layer(components);
|
||||
@import "../components/session-review.css" layer(components);
|
||||
@import "../components/session-turn.css" layer(components);
|
||||
@import "../components/shell-submessage.css" layer(components);
|
||||
|
||||
@@ -1,296 +1,313 @@
|
||||
/* Vite can link this before the app entry CSS, so name every layer here or `components` ranks below Tailwind's base reset. */
|
||||
@layer properties, theme, base, components, utilities;
|
||||
@import "../submit.css";
|
||||
|
||||
[data-component="button-v2"] {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
border-radius: 6px;
|
||||
font-style: normal;
|
||||
font-weight: 530;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
color: var(--v2-text-text-base);
|
||||
text-shadow: none;
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: -0.04px;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
||||
@layer components {
|
||||
[data-component="button-v2"] {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
border-radius: 6px;
|
||||
font-style: normal;
|
||||
font-weight: 530;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
color: var(--v2-text-text-base);
|
||||
text-shadow: none;
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: -0.04px;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
[data-component="button-v2"] > * {
|
||||
pointer-events: none;
|
||||
}
|
||||
[data-component="button-v2"] > * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
[data-component="button-v2"]:focus {
|
||||
outline: none;
|
||||
}
|
||||
[data-component="button-v2"]:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
[data-component="button-v2"]:is(:focus-visible, [data-state="focus"]):not(:disabled):not([data-variant="loading"]) {
|
||||
outline: 2px solid var(--v2-border-border-focus);
|
||||
outline-offset: 2.5px;
|
||||
}
|
||||
[data-component="button-v2"]:is(:focus-visible, [data-state="focus"]):not(:disabled):not([data-variant="loading"]) {
|
||||
outline: 2px solid var(--v2-border-border-focus);
|
||||
outline-offset: 2.5px;
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-size="normal"] {
|
||||
height: 28px;
|
||||
padding: 0 11px;
|
||||
}
|
||||
[data-component="button-v2"][data-size="normal"] {
|
||||
height: 28px;
|
||||
padding: 0 11px;
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-size="small"] {
|
||||
height: 24px;
|
||||
padding: 0 9px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
[data-component="button-v2"][data-size="small"] {
|
||||
height: 24px;
|
||||
padding: 0 9px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-size="large"] {
|
||||
height: 32px;
|
||||
padding: 0 15px;
|
||||
}
|
||||
[data-component="button-v2"][data-size="large"] {
|
||||
height: 32px;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-icon][data-size="small"] {
|
||||
padding-left: 9px;
|
||||
}
|
||||
[data-component="button-v2"][data-icon][data-size="small"] {
|
||||
padding-left: 9px;
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-icon][data-size="normal"] {
|
||||
padding-left: 11px;
|
||||
}
|
||||
[data-component="button-v2"][data-icon][data-size="normal"] {
|
||||
padding-left: 11px;
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-icon][data-size="large"] {
|
||||
padding-left: 15px;
|
||||
}
|
||||
[data-component="button-v2"][data-icon][data-size="large"] {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
[data-component="button-v2"] [data-slot="icon-svg"] {
|
||||
color: currentColor;
|
||||
}
|
||||
[data-component="button-v2"] [data-slot="icon-svg"] {
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
/* Neutral */
|
||||
[data-component="button-v2"][data-variant="neutral"] {
|
||||
background-color: var(--v2-background-bg-button-neutral);
|
||||
color: var(--v2-text-text-base);
|
||||
box-shadow: var(--v2-elevation-button-neutral);
|
||||
}
|
||||
/* Neutral */
|
||||
[data-component="button-v2"][data-variant="neutral"] {
|
||||
background-color: var(--v2-background-bg-button-neutral);
|
||||
color: var(--v2-text-text-base);
|
||||
box-shadow: var(--v2-elevation-button-neutral);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="neutral"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-hover) 0%, var(--v2-overlay-simple-overlay-hover) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="neutral"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-hover) 0%, var(--v2-overlay-simple-overlay-hover) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="neutral"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-pressed) 0%, var(--v2-overlay-simple-overlay-pressed) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="neutral"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-overlay-simple-overlay-pressed) 0%,
|
||||
var(--v2-overlay-simple-overlay-pressed) 100%
|
||||
),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="neutral"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
[data-component="button-v2"][data-variant="neutral"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Danger */
|
||||
[data-component="button-v2"][data-variant="danger"] {
|
||||
background-color: var(--v2-background-bg-button-neutral);
|
||||
color: var(--v2-state-fg-danger);
|
||||
box-shadow: var(--v2-elevation-button-neutral);
|
||||
}
|
||||
/* Danger */
|
||||
[data-component="button-v2"][data-variant="danger"] {
|
||||
background-color: var(--v2-background-bg-button-neutral);
|
||||
color: var(--v2-state-fg-danger);
|
||||
box-shadow: var(--v2-elevation-button-neutral);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="danger"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-hover) 0%, var(--v2-overlay-simple-overlay-hover) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="danger"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-hover) 0%, var(--v2-overlay-simple-overlay-hover) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="danger"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-pressed) 0%, var(--v2-overlay-simple-overlay-pressed) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="danger"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-overlay-simple-overlay-pressed) 0%,
|
||||
var(--v2-overlay-simple-overlay-pressed) 100%
|
||||
),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="danger"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
[data-component="button-v2"][data-variant="danger"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="warning"] {
|
||||
background-color: var(--v2-background-bg-button-neutral);
|
||||
color: var(--v2-state-fg-warning);
|
||||
box-shadow: var(--v2-elevation-button-neutral);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="warning"] {
|
||||
background-color: var(--v2-background-bg-button-neutral);
|
||||
color: var(--v2-state-fg-warning);
|
||||
box-shadow: var(--v2-elevation-button-neutral);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="warning"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-hover) 0%, var(--v2-overlay-simple-overlay-hover) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="warning"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-hover) 0%, var(--v2-overlay-simple-overlay-hover) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="warning"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-pressed) 0%, var(--v2-overlay-simple-overlay-pressed) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="warning"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-overlay-simple-overlay-pressed) 0%,
|
||||
var(--v2-overlay-simple-overlay-pressed) 100%
|
||||
),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="warning"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
[data-component="button-v2"][data-variant="warning"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Outline */
|
||||
[data-component="button-v2"][data-variant="outline"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-text-text-base);
|
||||
box-shadow: inset 0 0 0 1px var(--v2-border-border-muted);
|
||||
}
|
||||
/* Outline */
|
||||
[data-component="button-v2"][data-variant="outline"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-text-text-base);
|
||||
box-shadow: inset 0 0 0 1px var(--v2-border-border-muted);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="outline"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="outline"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="outline"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="outline"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="outline"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
[data-component="button-v2"][data-variant="outline"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Contrast */
|
||||
[data-component="button-v2"][data-variant="contrast"] {
|
||||
background-image:
|
||||
linear-gradient(180deg, var(--v2-alpha-light-20) 0%, var(--v2-alpha-light-0) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-contrast) 0%, var(--v2-background-bg-contrast) 100%);
|
||||
color: var(--v2-text-text-contrast);
|
||||
text-shadow: 0 0.5px 0.5px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: var(--v2-elevation-button-contrast);
|
||||
}
|
||||
/* Contrast */
|
||||
[data-component="button-v2"][data-variant="contrast"] {
|
||||
background-image:
|
||||
linear-gradient(180deg, var(--v2-alpha-light-20) 0%, var(--v2-alpha-light-0) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-contrast) 0%, var(--v2-background-bg-contrast) 100%);
|
||||
color: var(--v2-text-text-contrast);
|
||||
text-shadow: 0 0.5px 0.5px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: var(--v2-elevation-button-contrast);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="contrast"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-overlay-simple-overlay-contrast-hover) 0%,
|
||||
var(--v2-overlay-simple-overlay-contrast-hover) 100%
|
||||
),
|
||||
linear-gradient(180deg, var(--v2-alpha-light-20) 0%, var(--v2-alpha-light-0) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-contrast) 0%, var(--v2-background-bg-contrast) 100%);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="contrast"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-overlay-simple-overlay-contrast-hover) 0%,
|
||||
var(--v2-overlay-simple-overlay-contrast-hover) 100%
|
||||
),
|
||||
linear-gradient(180deg, var(--v2-alpha-light-20) 0%, var(--v2-alpha-light-0) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-contrast) 0%, var(--v2-background-bg-contrast) 100%);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="contrast"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-overlay-simple-overlay-contrast-pressed) 0%,
|
||||
var(--v2-overlay-simple-overlay-contrast-pressed) 100%
|
||||
),
|
||||
linear-gradient(180deg, var(--v2-alpha-light-20) 0%, var(--v2-alpha-light-0) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-contrast) 0%, var(--v2-background-bg-contrast) 100%);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="contrast"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-overlay-simple-overlay-contrast-pressed) 0%,
|
||||
var(--v2-overlay-simple-overlay-contrast-pressed) 100%
|
||||
),
|
||||
linear-gradient(180deg, var(--v2-alpha-light-20) 0%, var(--v2-alpha-light-0) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-contrast) 0%, var(--v2-background-bg-contrast) 100%);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="contrast"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
[data-component="button-v2"][data-variant="contrast"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Loading */
|
||||
[data-component="button-v2"][data-variant="loading"] {
|
||||
background: var(--v2-background-bg-layer-02);
|
||||
color: var(--v2-text-text-base);
|
||||
box-shadow: inset 0 0 0 0.5px var(--v2-border-border-muted);
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
}
|
||||
/* Loading */
|
||||
[data-component="button-v2"][data-variant="loading"] {
|
||||
background: var(--v2-background-bg-layer-02);
|
||||
color: var(--v2-text-text-base);
|
||||
box-shadow: inset 0 0 0 0.5px var(--v2-border-border-muted);
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Ghost */
|
||||
[data-component="button-v2"][data-variant="ghost"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-text-text-base);
|
||||
}
|
||||
/* Ghost */
|
||||
[data-component="button-v2"][data-variant="ghost"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-text-text-base);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost"]:is(:hover, [data-state="hover"]):not(:disabled):not(
|
||||
[data-expanded]
|
||||
) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost"]:where([data-expanded]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Ghost muted */
|
||||
[data-component="button-v2"][data-variant="ghost-muted"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-text-text-muted);
|
||||
font-weight: 440;
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-muted"] [data-slot="icon-svg"] {
|
||||
color: var(--v2-icon-icon-muted);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
[data-component="button-v2"][data-variant="ghost-muted"]:is(:hover, [data-state="hover"]):not(:disabled):not(
|
||||
[data-component="button-v2"][data-variant="ghost"]:is(:hover, [data-state="hover"]):not(:disabled):not(
|
||||
[data-expanded]
|
||||
) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-muted"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="ghost"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-muted"]:where([data-expanded]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
color: var(--v2-text-text-base);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="ghost"]:where([data-expanded]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-muted"]:where([data-expanded]):not(:disabled) [data-slot="icon-svg"] {
|
||||
color: var(--v2-icon-icon-base);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="ghost"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-muted"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
/* Ghost muted */
|
||||
[data-component="button-v2"][data-variant="ghost-muted"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-text-text-muted);
|
||||
font-weight: 440;
|
||||
}
|
||||
|
||||
/* Ghost faint */
|
||||
[data-component="button-v2"][data-variant="ghost-faint"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-text-text-faint);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="ghost-muted"] [data-slot="icon-svg"] {
|
||||
color: var(--v2-icon-icon-muted);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-faint"] [data-slot="icon-svg"] {
|
||||
color: var(--v2-icon-icon-faint);
|
||||
}
|
||||
@media (hover: hover) {
|
||||
[data-component="button-v2"][data-variant="ghost-muted"]:is(:hover, [data-state="hover"]):not(:disabled):not(
|
||||
[data-expanded]
|
||||
) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-faint"]:is(:hover, [data-state="hover"]):not(:disabled):not(
|
||||
[data-expanded]
|
||||
) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="ghost-muted"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-faint"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="ghost-muted"]:where([data-expanded]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
color: var(--v2-text-text-base);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-faint"]:where([data-expanded]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
[data-component="button-v2"][data-variant="ghost-muted"]:where([data-expanded]):not(:disabled)
|
||||
[data-slot="icon-svg"] {
|
||||
color: var(--v2-icon-icon-base);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-faint"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
[data-component="button-v2"][data-variant="ghost-muted"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Ghost faint */
|
||||
[data-component="button-v2"][data-variant="ghost-faint"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-text-text-faint);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-faint"] [data-slot="icon-svg"] {
|
||||
color: var(--v2-icon-icon-faint);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-faint"]:is(:hover, [data-state="hover"]):not(:disabled):not(
|
||||
[data-expanded]
|
||||
) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-faint"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-faint"]:where([data-expanded]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
|
||||
[data-component="button-v2"][data-variant="ghost-faint"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,120 +1,128 @@
|
||||
/* Vite can link this before the app entry CSS, so name every layer here or `components` ranks below Tailwind's base reset. */
|
||||
@layer properties, theme, base, components, utilities;
|
||||
@import "../submit.css";
|
||||
|
||||
[data-component="icon-button-v2"] {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px;
|
||||
color: var(--v2-text-text-base);
|
||||
user-select: none;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
cursor: default;
|
||||
}
|
||||
@layer components {
|
||||
[data-component="icon-button-v2"] {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px;
|
||||
color: var(--v2-text-text-base);
|
||||
user-select: none;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"]:focus {
|
||||
outline: none;
|
||||
}
|
||||
[data-component="icon-button-v2"]:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"]:is(:focus-visible, [data-state="focus"]):not(:disabled) {
|
||||
outline: 2px solid var(--v2-border-border-focus);
|
||||
outline-offset: 2.5px;
|
||||
}
|
||||
[data-component="icon-button-v2"]:is(:focus-visible, [data-state="focus"]):not(:disabled) {
|
||||
outline: 2px solid var(--v2-border-border-focus);
|
||||
outline-offset: 2.5px;
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-size="small"] {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
[data-component="icon-button-v2"][data-size="small"] {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-size="normal"] {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
[data-component="icon-button-v2"][data-size="normal"] {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-size="large"] {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
[data-component="icon-button-v2"][data-size="large"] {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"] [data-slot="icon-svg"] {
|
||||
color: currentColor;
|
||||
}
|
||||
[data-component="icon-button-v2"] [data-slot="icon-svg"] {
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
/* Neutral */
|
||||
[data-component="icon-button-v2"][data-variant="neutral"] {
|
||||
background-color: var(--v2-background-bg-button-neutral);
|
||||
color: var(--v2-text-text-base);
|
||||
box-shadow: var(--v2-elevation-button-neutral);
|
||||
}
|
||||
/* Neutral */
|
||||
[data-component="icon-button-v2"][data-variant="neutral"] {
|
||||
background-color: var(--v2-background-bg-button-neutral);
|
||||
color: var(--v2-text-text-base);
|
||||
box-shadow: var(--v2-elevation-button-neutral);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-variant="neutral"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-hover) 0%, var(--v2-overlay-simple-overlay-hover) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
[data-component="icon-button-v2"][data-variant="neutral"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-hover) 0%, var(--v2-overlay-simple-overlay-hover) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-variant="neutral"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--v2-overlay-simple-overlay-pressed) 0%, var(--v2-overlay-simple-overlay-pressed) 100%),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
[data-component="icon-button-v2"][data-variant="neutral"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-overlay-simple-overlay-pressed) 0%,
|
||||
var(--v2-overlay-simple-overlay-pressed) 100%
|
||||
),
|
||||
linear-gradient(90deg, var(--v2-background-bg-button-neutral) 0%, var(--v2-background-bg-button-neutral) 100%);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-variant="neutral"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
[data-component="icon-button-v2"][data-variant="neutral"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Ghost */
|
||||
[data-component="icon-button-v2"][data-variant="ghost"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-text-text-base);
|
||||
}
|
||||
/* Ghost */
|
||||
[data-component="icon-button-v2"][data-variant="ghost"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-text-text-base);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-variant="ghost"]:is(:hover, [data-state="hover"]):not(:disabled):not(
|
||||
[data-expanded]
|
||||
) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
[data-component="icon-button-v2"][data-variant="ghost"]:is(:hover, [data-state="hover"]):not(:disabled):not(
|
||||
[data-expanded]
|
||||
) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-variant="ghost"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
[data-component="icon-button-v2"][data-variant="ghost"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-variant="ghost"]:where([data-expanded]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
[data-component="icon-button-v2"][data-variant="ghost"]:where([data-expanded]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-variant="ghost"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
[data-component="icon-button-v2"][data-variant="ghost"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Ghost */
|
||||
[data-component="icon-button-v2"][data-variant="ghost-muted"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-icon-icon-muted);
|
||||
}
|
||||
/* Ghost */
|
||||
[data-component="icon-button-v2"][data-variant="ghost-muted"] {
|
||||
background-color: transparent;
|
||||
color: var(--v2-icon-icon-muted);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-variant="ghost-muted"]:is(:hover, [data-state="hover"]):not(:disabled):not(
|
||||
[data-expanded]
|
||||
) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
[data-component="icon-button-v2"][data-variant="ghost-muted"]:is(:hover, [data-state="hover"]):not(:disabled):not(
|
||||
[data-expanded]
|
||||
) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-variant="ghost-muted"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
color: var(--v2-icon-icon-base);
|
||||
}
|
||||
[data-component="icon-button-v2"][data-variant="ghost-muted"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
color: var(--v2-icon-icon-base);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-variant="ghost-muted"]:where([data-expanded]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
color: var(--v2-icon-icon-base);
|
||||
}
|
||||
[data-component="icon-button-v2"][data-variant="ghost-muted"]:where([data-expanded]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
color: var(--v2-icon-icon-base);
|
||||
}
|
||||
|
||||
[data-component="icon-button-v2"][data-variant="ghost-muted"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
[data-component="icon-button-v2"][data-variant="ghost-muted"]:is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,68 @@
|
||||
/* Shared by Composer submit actions and contrast icon buttons. */
|
||||
:is(
|
||||
[data-component="button-v2"][data-variant="submit"],
|
||||
[data-component="icon-button-v2"]:is([data-variant="submit"], [data-variant="contrast"])
|
||||
) {
|
||||
--submit-highlight: var(--v2-alpha-light-20);
|
||||
--submit-hover: var(--v2-overlay-simple-overlay-contrast-hover);
|
||||
/* Vite can link this before the app entry CSS, so name every layer here or `components` ranks below Tailwind's base reset. */
|
||||
@layer properties, theme, base, components, utilities;
|
||||
|
||||
background-image:
|
||||
linear-gradient(180deg, var(--submit-highlight) 0%, var(--v2-alpha-light-0) 100%),
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-background-bg-icon-button-contrast) 0%,
|
||||
var(--v2-background-bg-icon-button-contrast) 100%
|
||||
);
|
||||
color: var(--v2-text-text-contrast);
|
||||
text-shadow: 0 0.5px 0.5px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: var(--v2-elevation-button-contrast);
|
||||
}
|
||||
|
||||
[data-color-scheme="dark"]
|
||||
@layer components {
|
||||
/* Shared by Composer submit actions and contrast icon buttons. */
|
||||
:is(
|
||||
[data-component="button-v2"][data-variant="submit"],
|
||||
[data-component="icon-button-v2"]:is([data-variant="submit"], [data-variant="contrast"])
|
||||
) {
|
||||
--submit-highlight: var(--v2-alpha-light-60);
|
||||
--submit-hover: var(--v2-alpha-dark-8);
|
||||
--submit-highlight: var(--v2-alpha-light-20);
|
||||
--submit-hover: var(--v2-overlay-simple-overlay-contrast-hover);
|
||||
|
||||
color: var(--v2-text-text-inverse);
|
||||
}
|
||||
background-image:
|
||||
linear-gradient(180deg, var(--submit-highlight) 0%, var(--v2-alpha-light-0) 100%),
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-background-bg-icon-button-contrast) 0%,
|
||||
var(--v2-background-bg-icon-button-contrast) 100%
|
||||
);
|
||||
color: var(--v2-text-text-contrast);
|
||||
text-shadow: 0 0.5px 0.5px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: var(--v2-elevation-button-contrast);
|
||||
}
|
||||
|
||||
[data-color-scheme="dark"] [data-component="icon-button-v2"]:is([data-variant="submit"], [data-variant="contrast"]) {
|
||||
color: var(--v2-icon-icon-inverse);
|
||||
}
|
||||
[data-color-scheme="dark"]
|
||||
:is(
|
||||
[data-component="button-v2"][data-variant="submit"],
|
||||
[data-component="icon-button-v2"]:is([data-variant="submit"], [data-variant="contrast"])
|
||||
) {
|
||||
--submit-highlight: var(--v2-alpha-light-60);
|
||||
--submit-hover: var(--v2-alpha-dark-8);
|
||||
|
||||
color: var(--v2-text-text-inverse);
|
||||
}
|
||||
|
||||
[data-color-scheme="dark"] [data-component="icon-button-v2"]:is([data-variant="submit"], [data-variant="contrast"]) {
|
||||
color: var(--v2-icon-icon-inverse);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
:is(
|
||||
[data-component="button-v2"][data-variant="submit"],
|
||||
[data-component="icon-button-v2"]:is([data-variant="submit"], [data-variant="contrast"])
|
||||
):is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--submit-hover) 0%, var(--submit-hover) 100%),
|
||||
linear-gradient(180deg, var(--submit-highlight) 0%, var(--v2-alpha-light-0) 100%),
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-background-bg-icon-button-contrast) 0%,
|
||||
var(--v2-background-bg-icon-button-contrast) 100%
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
:is(
|
||||
[data-component="button-v2"][data-variant="submit"],
|
||||
[data-component="icon-button-v2"]:is([data-variant="submit"], [data-variant="contrast"])
|
||||
):is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
):is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(90deg, var(--submit-hover) 0%, var(--submit-hover) 100%),
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-overlay-simple-overlay-contrast-pressed) 0%,
|
||||
var(--v2-overlay-simple-overlay-contrast-pressed) 100%
|
||||
),
|
||||
linear-gradient(180deg, var(--submit-highlight) 0%, var(--v2-alpha-light-0) 100%),
|
||||
linear-gradient(
|
||||
90deg,
|
||||
@@ -47,30 +70,12 @@
|
||||
var(--v2-background-bg-icon-button-contrast) 100%
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
:is(
|
||||
:is(
|
||||
[data-component="button-v2"][data-variant="submit"],
|
||||
[data-component="icon-button-v2"]:is([data-variant="submit"], [data-variant="contrast"])
|
||||
):is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-image:
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-overlay-simple-overlay-contrast-pressed) 0%,
|
||||
var(--v2-overlay-simple-overlay-contrast-pressed) 100%
|
||||
),
|
||||
linear-gradient(180deg, var(--submit-highlight) 0%, var(--v2-alpha-light-0) 100%),
|
||||
linear-gradient(
|
||||
90deg,
|
||||
var(--v2-background-bg-icon-button-contrast) 0%,
|
||||
var(--v2-background-bg-icon-button-contrast) 100%
|
||||
);
|
||||
}
|
||||
|
||||
:is(
|
||||
[data-component="button-v2"][data-variant="submit"],
|
||||
[data-component="icon-button-v2"]:is([data-variant="submit"], [data-variant="contrast"])
|
||||
):is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
):is(:disabled, [data-state="disabled"]) {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,181 +1,186 @@
|
||||
[data-component="text-input-v2"] {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
padding-block: 0;
|
||||
padding-inline: 0 8px;
|
||||
gap: 8px;
|
||||
width: 280px;
|
||||
height: 28px;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
outline: 1px solid transparent;
|
||||
outline-offset: 0;
|
||||
background:
|
||||
linear-gradient(180deg, var(--v2-alpha-light-6) 0%, var(--v2-alpha-light-2) 100%), var(--v2-background-bg-base);
|
||||
box-shadow: var(--v2-elevation-button-neutral);
|
||||
flex: none;
|
||||
align-self: stretch;
|
||||
transition:
|
||||
background 85ms ease-out,
|
||||
outline-color 85ms ease-out,
|
||||
box-shadow 85ms ease-out;
|
||||
}
|
||||
/* Vite can link this before the app entry CSS, so name every layer here or `components` ranks below Tailwind's base reset. */
|
||||
@layer properties, theme, base, components, utilities;
|
||||
|
||||
[data-component="text-input-v2"][data-appearance="large"] {
|
||||
height: 32px;
|
||||
}
|
||||
@layer components {
|
||||
[data-component="text-input-v2"] {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
padding-block: 0;
|
||||
padding-inline: 0 8px;
|
||||
gap: 8px;
|
||||
width: 280px;
|
||||
height: 28px;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
outline: 1px solid transparent;
|
||||
outline-offset: 0;
|
||||
background:
|
||||
linear-gradient(180deg, var(--v2-alpha-light-6) 0%, var(--v2-alpha-light-2) 100%), var(--v2-background-bg-base);
|
||||
box-shadow: var(--v2-elevation-button-neutral);
|
||||
flex: none;
|
||||
align-self: stretch;
|
||||
transition:
|
||||
background 85ms ease-out,
|
||||
outline-color 85ms ease-out,
|
||||
box-shadow 85ms ease-out;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"]:where(:hover):not([data-disabled], [data-invalid]):not(:focus-within) {
|
||||
background:
|
||||
linear-gradient(0deg, var(--v2-overlay-simple-overlay-hover), var(--v2-overlay-simple-overlay-hover)),
|
||||
linear-gradient(180deg, var(--v2-alpha-light-6) 0%, var(--v2-alpha-light-2) 100%), var(--v2-background-bg-base);
|
||||
}
|
||||
[data-component="text-input-v2"][data-appearance="large"] {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"]:where(:focus-within):not([data-disabled], [data-invalid]) {
|
||||
outline-color: var(--v2-border-border-focus);
|
||||
box-shadow: none;
|
||||
}
|
||||
[data-component="text-input-v2"]:where(:hover):not([data-disabled], [data-invalid]):not(:focus-within) {
|
||||
background:
|
||||
linear-gradient(0deg, var(--v2-overlay-simple-overlay-hover), var(--v2-overlay-simple-overlay-hover)),
|
||||
linear-gradient(180deg, var(--v2-alpha-light-6) 0%, var(--v2-alpha-light-2) 100%), var(--v2-background-bg-base);
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"]:where([data-invalid]):not([data-disabled]) {
|
||||
outline-color: var(--v2-state-fg-danger);
|
||||
box-shadow: none;
|
||||
}
|
||||
[data-component="text-input-v2"]:where(:focus-within):not([data-disabled], [data-invalid]) {
|
||||
outline-color: var(--v2-border-border-focus);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"]:where([data-disabled]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
[data-component="text-input-v2"]:where([data-invalid]):not([data-disabled]) {
|
||||
outline-color: var(--v2-state-fg-danger);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-value"] {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
align-self: stretch;
|
||||
padding: 0;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
}
|
||||
[data-component="text-input-v2"]:where([data-disabled]) {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-leading-icon"] {
|
||||
display: flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-inline-start: 8px;
|
||||
color: var(--v2-icon-icon-muted);
|
||||
}
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-value"] {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
align-self: stretch;
|
||||
padding: 0;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-leading-icon"] :is(svg, [data-slot="icon-svg"]) {
|
||||
display: block;
|
||||
flex: none;
|
||||
}
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-leading-icon"] {
|
||||
display: flex;
|
||||
flex: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-inline-start: 8px;
|
||||
color: var(--v2-icon-icon-muted);
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"][data-leading-icon] [data-slot="text-input-v2-input"] {
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-leading-icon"] :is(svg, [data-slot="icon-svg"]) {
|
||||
display: block;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-input"] {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
height: 100%;
|
||||
padding-block: 0;
|
||||
padding-inline: 8px 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
font-style: normal;
|
||||
font-weight: 440;
|
||||
font-size: 13px;
|
||||
line-height: var(--line-height-compact);
|
||||
letter-spacing: -0.04px;
|
||||
color: var(--v2-text-text-base);
|
||||
font-variation-settings: "slnt" 0;
|
||||
}
|
||||
[data-component="text-input-v2"][data-leading-icon] [data-slot="text-input-v2-input"] {
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-input"]::placeholder {
|
||||
color: var(--v2-text-text-faint);
|
||||
user-select: none;
|
||||
}
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-input"] {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
height: 100%;
|
||||
padding-block: 0;
|
||||
padding-inline: 8px 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
font-style: normal;
|
||||
font-weight: 440;
|
||||
font-size: 13px;
|
||||
line-height: var(--line-height-compact);
|
||||
letter-spacing: -0.04px;
|
||||
color: var(--v2-text-text-base);
|
||||
font-variation-settings: "slnt" 0;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-input"][type="search"]::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
display: none;
|
||||
}
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-input"]::placeholder {
|
||||
color: var(--v2-text-text-faint);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"][data-numeric] [data-slot="text-input-v2-input"] {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-input"][type="search"]::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-icon-button"] {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
align-self: center;
|
||||
flex: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 2px;
|
||||
gap: 3px;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
color: var(--v2-icon-icon-muted);
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
||||
[data-component="text-input-v2"][data-numeric] [data-slot="text-input-v2-input"] {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"]
|
||||
[data-slot="text-input-v2-icon-button"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-icon-button"] {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
align-self: center;
|
||||
flex: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding: 2px;
|
||||
gap: 3px;
|
||||
border: 0;
|
||||
border-radius: 4px;
|
||||
background: transparent;
|
||||
color: var(--v2-icon-icon-muted);
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"]
|
||||
[data-slot="text-input-v2-icon-button"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
[data-component="text-input-v2"]
|
||||
[data-slot="text-input-v2-icon-button"]:is(:hover, [data-state="hover"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-hover);
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-icon-button"]:focus {
|
||||
outline: none;
|
||||
}
|
||||
[data-component="text-input-v2"]
|
||||
[data-slot="text-input-v2-icon-button"]:is(:active, [data-state="pressed"]):not(:disabled) {
|
||||
background-color: var(--v2-overlay-simple-overlay-pressed);
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-icon-button"]:focus-visible {
|
||||
outline: 2px solid var(--v2-border-border-focus);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-icon-button"]:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"]:where([data-disabled]) [data-slot="text-input-v2-icon-button"] {
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
}
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-icon-button"]:focus-visible {
|
||||
outline: 2px solid var(--v2-border-border-focus);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-icon-button"] [data-slot="icon-svg"] {
|
||||
display: block;
|
||||
flex: none;
|
||||
color: currentColor;
|
||||
}
|
||||
[data-component="text-input-v2"]:where([data-disabled]) [data-slot="text-input-v2-icon-button"] {
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-icon-button"][data-variant="clear"] {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 0;
|
||||
border-radius: 6px;
|
||||
margin-inline-end: -8px;
|
||||
}
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-icon-button"] [data-slot="icon-svg"] {
|
||||
display: block;
|
||||
flex: none;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"][data-invalid]:not([data-disabled]) [data-slot="text-input-v2-input"] {
|
||||
color: var(--v2-state-fg-danger);
|
||||
caret-color: var(--v2-state-fg-danger);
|
||||
}
|
||||
[data-component="text-input-v2"] [data-slot="text-input-v2-icon-button"][data-variant="clear"] {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 0;
|
||||
border-radius: 6px;
|
||||
margin-inline-end: -8px;
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"][data-invalid]:not([data-disabled]) [data-slot="text-input-v2-input"]::placeholder {
|
||||
color: var(--v2-state-fg-danger);
|
||||
opacity: 1;
|
||||
[data-component="text-input-v2"][data-invalid]:not([data-disabled]) [data-slot="text-input-v2-input"] {
|
||||
color: var(--v2-state-fg-danger);
|
||||
caret-color: var(--v2-state-fg-danger);
|
||||
}
|
||||
|
||||
[data-component="text-input-v2"][data-invalid]:not([data-disabled]) [data-slot="text-input-v2-input"]::placeholder {
|
||||
color: var(--v2-state-fg-danger);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,6 +279,7 @@ const source = {
|
||||
"ui.question.multiHint": "Select all answers that apply",
|
||||
"ui.question.singleHint": "Select one answer",
|
||||
"ui.question.custom.placeholder": "Type your answer…",
|
||||
"ui.question.custom.answerPlaceholder": "Type your own answer…",
|
||||
} satisfies Record<string, string>
|
||||
|
||||
export type Key = keyof typeof source
|
||||
|
||||
Reference in New Issue
Block a user