Files
openidea/src/ui/Button.module.css
T
ntbang0901andNguyenBang 16bf9b53a2 feat(plugins): show a running state on a plugin command's toolbar button (#2371)
A plugin command that takes seconds (an LLM call that fills the commit message) gave no
sign at the button that the click was taken, and a second click started a second run.

Actions may now set `indicatesRunning`: the action runner counts their in-flight runs
and an IconButton bound to such an action shows a spinner, sets aria-busy and ignores
clicks until the run settles. Plugin commands set it, so every toolbar slot that draws
them (editor.title, mainToolbar, commit.message) is covered without a plugin API change
and without features importing each other. The button stays focusable (aria-disabled,
not disabled). Spinner moves to its own module so Button can use it without a cycle
with Feedback, which re-exports it.

Refs #2254

Co-authored-by: NguyenBang <nguyenbang@Mac.lan>
2026-11-09 22:43:53 +08:00

144 lines
3.2 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* IntelliJ new UI buttons: Button.arc 8 (radius 4), minimumSize 72×28, 2px focus ring outside. */
.button {
--button-radius: var(--radius-control, 4px);
display: inline-flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
gap: 6px;
height: var(--h-button, 28px);
min-width: 72px;
padding: 0 16px;
border-radius: var(--button-radius);
font-size: var(--fs-ui);
line-height: 1;
white-space: nowrap;
transition:
background var(--dur-fast) var(--ease),
color var(--dur-fast) var(--ease),
box-shadow var(--dur-fast) var(--ease);
}
.button:focus-visible {
outline: 2px solid var(--focus-ring);
outline-offset: 1px;
}
.button:disabled {
cursor: default;
}
.small {
height: var(--h-control);
min-width: 0;
padding: 0 10px;
}
.primary {
background: var(--bg-button-primary);
color: var(--fg-button-primary);
--icon-color: currentColor;
}
.primary:not(:disabled):hover {
background: var(--bg-button-primary-hover);
}
.secondary {
background: var(--bg-button);
color: var(--fg-strong);
box-shadow: inset 0 0 0 1px var(--border-button);
}
.secondary:not(:disabled):hover {
background: color-mix(in srgb, var(--bg-button) 94%, var(--fg-strong));
}
.primary:disabled,
.secondary:disabled {
background: transparent;
color: var(--fg-faint);
box-shadow: inset 0 0 0 1px var(--border);
}
.ghost {
min-width: 0;
padding: 0 8px;
color: var(--fg-secondary);
}
.ghost:not(:disabled):hover {
background: var(--bg-toolbar-hover);
color: var(--fg-strong);
}
.ghost:not(:disabled):active {
background: var(--bg-toolbar-pressed, color-mix(in srgb, var(--fg-strong) 12%, transparent));
}
.ghost:disabled {
color: var(--fg-faint);
}
/* Toolbar / action buttons: transparent on hover, filled when pressed or selected. */
.iconButton {
flex: none;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-toolbar-button, 6px);
color: var(--fg-muted);
transition:
background var(--dur-fast) var(--ease),
color var(--dur-fast) var(--ease);
}
.iconButton:focus-visible {
outline: 2px solid var(--focus-ring);
outline-offset: -2px;
}
.iconButton:not(:disabled):hover {
color: var(--fg-strong);
}
.iconButton:not(:disabled):active {
background: var(--bg-toolbar-pressed, color-mix(in srgb, var(--fg-strong) 12%, transparent));
}
.iconButton:disabled {
opacity: 0.4;
cursor: default;
}
.iconButton[aria-busy="true"] {
cursor: progress;
}
.iconButton[aria-pressed="true"] {
background: var(--bg-toolbar-selected, var(--bg-tree-selected));
color: var(--fg-strong);
}
.iconButton[aria-pressed="true"]:not(:disabled):hover {
background: var(--bg-toolbar-selected-hover, color-mix(in srgb, var(--bg-tree-selected) 85%, var(--fg-strong)));
}
.is-small {
width: 20px;
height: 20px;
border-radius: var(--radius-small);
}
.is-normal {
width: 24px;
height: 24px;
}
.is-large {
width: 28px;
height: 28px;
}
.tone-danger {
color: var(--danger);
}
.tone-accent {
color: var(--accent);
}
@media (prefers-reduced-motion: reduce) {
.button,
.iconButton {
transition: none;
}
}
@media (forced-colors: active) {
.secondary,
.primary {
border: 1px solid ButtonText;
}
}