From 47199ad9c57e5e8b0ddaab88f3398e6577e5ca29 Mon Sep 17 00:00:00 2001 From: Anthony Stewart <150152+a-stewart@users.noreply.github.com> Date: Thu, 15 May 2025 15:02:22 +0200 Subject: [PATCH 01/10] Add support for split buttons --- src/main.ts | 2 + src/vscode-button/vscode-button.styles.ts | 18 ++++++-- src/vscode-split-button-divider/index.ts | 1 + .../vscode-split-button-divider.ts | 46 +++++++++++++++++++ src/vscode-split-button/index.ts | 1 + .../vscode-split-button.styles.ts | 32 +++++++++++++ .../vscode-split-button.ts | 36 +++++++++++++++ 7 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 src/vscode-split-button-divider/index.ts create mode 100644 src/vscode-split-button-divider/vscode-split-button-divider.ts create mode 100644 src/vscode-split-button/index.ts create mode 100644 src/vscode-split-button/vscode-split-button.styles.ts create mode 100644 src/vscode-split-button/vscode-split-button.ts diff --git a/src/main.ts b/src/main.ts index 1e11e818e..94081fc04 100644 --- a/src/main.ts +++ b/src/main.ts @@ -18,6 +18,8 @@ export {VscodeRadio} from './vscode-radio/index.js'; export {VscodeRadioGroup} from './vscode-radio-group/index.js'; export {VscodeSingleSelect} from './vscode-single-select/index.js'; export {VscodeScrollable} from './vscode-scrollable/index.js'; +export {VscodeSplitButton} from './vscode-split-button/index.js'; +export {VscodeSplitButtonDivider} from './vscode-split-button-divider/index.js'; export {VscodeSplitLayout} from './vscode-split-layout/index.js'; export {VscodeTabHeader} from './vscode-tab-header/index.js'; export {VscodeTabPanel} from './vscode-tab-panel/index.js'; diff --git a/src/vscode-button/vscode-button.styles.ts b/src/vscode-button/vscode-button.styles.ts index 78da388e7..fd6198495 100644 --- a/src/vscode-button/vscode-button.styles.ts +++ b/src/vscode-button/vscode-button.styles.ts @@ -26,6 +26,10 @@ const styles: CSSResultGroup = [ white-space: nowrap; } + :host(:empty) { + padding: 1px 5px; + } + :host([secondary]) { color: var(--vscode-button-secondaryForeground, #cccccc); background-color: var(--vscode-button-secondaryBackground, #313131); @@ -91,6 +95,10 @@ const styles: CSSResultGroup = [ margin-left: 0; } + ::slotted(*:last-child) { + margin-right: 0; + } + ::slotted(vscode-icon) { color: inherit; } @@ -102,6 +110,7 @@ const styles: CSSResultGroup = [ justify-content: center; position: relative; width: 100%; + height: 100%; } slot { @@ -110,15 +119,16 @@ const styles: CSSResultGroup = [ height: 100%; } - .icon { + .icon, .icon-after { color: inherit; display: block; + } + + :host(:not(:empty)) .icon { margin-right: 3px; } - .icon-after { - color: inherit; - display: block; + :host(:not(:empty)) .icon-after, :host([icon]) .icon-after { margin-left: 3px; } `, diff --git a/src/vscode-split-button-divider/index.ts b/src/vscode-split-button-divider/index.ts new file mode 100644 index 000000000..0ed7e80e3 --- /dev/null +++ b/src/vscode-split-button-divider/index.ts @@ -0,0 +1 @@ +export {VscodeSplitButtonDivider} from './vscode-split-button-divider.js'; diff --git a/src/vscode-split-button-divider/vscode-split-button-divider.ts b/src/vscode-split-button-divider/vscode-split-button-divider.ts new file mode 100644 index 000000000..7e2dfc6df --- /dev/null +++ b/src/vscode-split-button-divider/vscode-split-button-divider.ts @@ -0,0 +1,46 @@ +import {css, html, TemplateResult} from 'lit'; +import {customElement, property} from 'lit/decorators.js'; +import {VscElement} from '../includes/VscElement.js'; + +/** + * A divider to show between two buttons in a split button. + * + * @tag vscode-split-button-divider + */ +@customElement('vscode-split-button-divider') +export class VscodeSplitButtonDivider extends VscElement { + static override get styles() { + return css` + :host { + background-color: var(--vscode-button-background, #0078d4); + padding: 4px 0; + display: flex; + box-sizing: border-box; + } + :host([secondary]) { + background-color: var(--vscode-button-secondaryBackground, #313131); + } + div { + background-color: var(--vscode-button-separator); + width: 1px; + margin: 0; + } + `; + } + + /** + * Button has a less prominent style. + */ + @property({type: Boolean, reflect: true}) + secondary = false; + + override render() { + return html`
`; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'vscode-split-button-divider': VscodeSplitButtonDivider; + } +} diff --git a/src/vscode-split-button/index.ts b/src/vscode-split-button/index.ts new file mode 100644 index 000000000..61908b88e --- /dev/null +++ b/src/vscode-split-button/index.ts @@ -0,0 +1 @@ +export {VscodeSplitButton} from './vscode-split-button.js'; diff --git a/src/vscode-split-button/vscode-split-button.styles.ts b/src/vscode-split-button/vscode-split-button.styles.ts new file mode 100644 index 000000000..2eeb0aa71 --- /dev/null +++ b/src/vscode-split-button/vscode-split-button.styles.ts @@ -0,0 +1,32 @@ +import {css, CSSResultGroup} from 'lit'; + +import defaultStyles from '../includes/default.styles.js'; +import {getDefaultFontStack} from '../includes/helpers.js'; + +const defaultFontStack = getDefaultFontStack(); + +const styles: CSSResultGroup = [ + defaultStyles, + css` + :host { + display: flex; + align-items: stretch; + padding: 0; + border: none; + } + + ::slotted(vscode-button:not(:first-child)) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-left-width: 0; + } + + ::slotted(vscode-button:not(:last-child)) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right-width: 0; + } + `, +]; + +export default styles; \ No newline at end of file diff --git a/src/vscode-split-button/vscode-split-button.ts b/src/vscode-split-button/vscode-split-button.ts new file mode 100644 index 000000000..2b7883f39 --- /dev/null +++ b/src/vscode-split-button/vscode-split-button.ts @@ -0,0 +1,36 @@ +import {html, TemplateResult} from 'lit'; +import {customElement, property} from 'lit/decorators.js'; +import {VscElement} from '../includes/VscElement.js'; +import styles from './vscode-split-button.styles.js'; + +/** + * Shows a split button, including several components in a single button. Commonly used to show a button with a dropdown to the right. + * + * @tag vscode-split-button + * + * @cssprop [--vscode-button-background=#0078d4] + * @cssprop [--vscode-button-foreground=#ffffff] + * @cssprop [--vscode-button-border=var(--vscode-button-background, rgba(255, 255, 255, 0.07))] + * @cssprop [--vscode-button-hoverBackground=#026ec1] + * @cssprop [--vscode-font-family=sans-serif] - A sans-serif font type depends on the host OS. + * @cssprop [--vscode-font-size=13px] + * @cssprop [--vscode-font-weight=normal] + * @cssprop [--vscode-button-secondaryForeground=#cccccc] + * @cssprop [--vscode-button-secondaryBackground=#313131] + * @cssprop [--vscode-button-secondaryHoverBackground=#3c3c3c] + * @cssprop [--vscode-focusBorder=#0078d4] + */ +@customElement('vscode-split-button') +export class VscodeSplitButton extends VscElement { + static override styles = styles; + + override render(): TemplateResult { + return html` `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'vscode-split-button': VscodeSplitButton; + } +} From 176e12b2e3362cef39f630667ba5d1c9d80ef723 Mon Sep 17 00:00:00 2001 From: Anthony Stewart <150152+a-stewart@users.noreply.github.com> Date: Thu, 15 May 2025 20:23:01 +0200 Subject: [PATCH 02/10] Remove and add a div after vscode-button instead --- src/main.ts | 1 - src/vscode-button/vscode-button.styles.ts | 30 +++++++++--- src/vscode-button/vscode-button.ts | 1 + src/vscode-split-button-divider/index.ts | 1 - .../vscode-split-button-divider.ts | 46 ------------------- 5 files changed, 25 insertions(+), 54 deletions(-) delete mode 100644 src/vscode-split-button-divider/index.ts delete mode 100644 src/vscode-split-button-divider/vscode-split-button-divider.ts diff --git a/src/main.ts b/src/main.ts index 94081fc04..21b3ac1a4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -19,7 +19,6 @@ export {VscodeRadioGroup} from './vscode-radio-group/index.js'; export {VscodeSingleSelect} from './vscode-single-select/index.js'; export {VscodeScrollable} from './vscode-scrollable/index.js'; export {VscodeSplitButton} from './vscode-split-button/index.js'; -export {VscodeSplitButtonDivider} from './vscode-split-button-divider/index.js'; export {VscodeSplitLayout} from './vscode-split-layout/index.js'; export {VscodeTabHeader} from './vscode-tab-header/index.js'; export {VscodeTabPanel} from './vscode-tab-panel/index.js'; diff --git a/src/vscode-button/vscode-button.styles.ts b/src/vscode-button/vscode-button.styles.ts index fd6198495..dc0c90ff6 100644 --- a/src/vscode-button/vscode-button.styles.ts +++ b/src/vscode-button/vscode-button.styles.ts @@ -15,21 +15,17 @@ const styles: CSSResultGroup = [ border-width: 1px; color: var(--vscode-button-foreground, #ffffff); cursor: pointer; - display: inline-block; + display: inline-flex; font-family: var(--vscode-font-family, ${defaultFontStack}); font-size: var(--vscode-font-size, 13px); font-weight: var(--vscode-font-weight, normal); line-height: 22px; overflow: hidden; - padding: 1px 13px; + padding: 0; user-select: none; white-space: nowrap; } - :host(:empty) { - padding: 1px 5px; - } - :host([secondary]) { color: var(--vscode-button-secondaryForeground, #cccccc); background-color: var(--vscode-button-secondaryBackground, #313131); @@ -111,6 +107,11 @@ const styles: CSSResultGroup = [ position: relative; width: 100%; height: 100%; + padding: 1px 13px; + } + + :host(:empty) .wrapper { + padding: 1px 5px; } slot { @@ -131,6 +132,23 @@ const styles: CSSResultGroup = [ :host(:not(:empty)) .icon-after, :host([icon]) .icon-after { margin-left: 3px; } + + .divider { + display: var(--divider-display, none); + background-color: var(--vscode-button-background, #0078d4); + padding: 4px 0; + box-sizing: border-box; + } + + :host([secondary]) .divider { + background-color: var(--vscode-button-secondaryBackground, #313131); + } + + .divider > div { + background-color: var(--vscode-button-separator); + width: 1px; + margin: 0; + } `, ]; diff --git a/src/vscode-button/vscode-button.ts b/src/vscode-button/vscode-button.ts index 995ebf5cb..66208d23a 100644 --- a/src/vscode-button/vscode-button.ts +++ b/src/vscode-button/vscode-button.ts @@ -267,6 +267,7 @@ export class VscodeButton extends VscElement { ${iconAfterElem} +
`; } } diff --git a/src/vscode-split-button-divider/index.ts b/src/vscode-split-button-divider/index.ts deleted file mode 100644 index 0ed7e80e3..000000000 --- a/src/vscode-split-button-divider/index.ts +++ /dev/null @@ -1 +0,0 @@ -export {VscodeSplitButtonDivider} from './vscode-split-button-divider.js'; diff --git a/src/vscode-split-button-divider/vscode-split-button-divider.ts b/src/vscode-split-button-divider/vscode-split-button-divider.ts deleted file mode 100644 index 7e2dfc6df..000000000 --- a/src/vscode-split-button-divider/vscode-split-button-divider.ts +++ /dev/null @@ -1,46 +0,0 @@ -import {css, html, TemplateResult} from 'lit'; -import {customElement, property} from 'lit/decorators.js'; -import {VscElement} from '../includes/VscElement.js'; - -/** - * A divider to show between two buttons in a split button. - * - * @tag vscode-split-button-divider - */ -@customElement('vscode-split-button-divider') -export class VscodeSplitButtonDivider extends VscElement { - static override get styles() { - return css` - :host { - background-color: var(--vscode-button-background, #0078d4); - padding: 4px 0; - display: flex; - box-sizing: border-box; - } - :host([secondary]) { - background-color: var(--vscode-button-secondaryBackground, #313131); - } - div { - background-color: var(--vscode-button-separator); - width: 1px; - margin: 0; - } - `; - } - - /** - * Button has a less prominent style. - */ - @property({type: Boolean, reflect: true}) - secondary = false; - - override render() { - return html`
`; - } -} - -declare global { - interface HTMLElementTagNameMap { - 'vscode-split-button-divider': VscodeSplitButtonDivider; - } -} From 651e91fe52d0276bd873e4297e43a0b15e0c5193 Mon Sep 17 00:00:00 2001 From: Anthony Stewart <150152+a-stewart@users.noreply.github.com> Date: Thu, 15 May 2025 20:30:23 +0200 Subject: [PATCH 03/10] Rename to vscode-button-group and remove the divider tag in favour of adding automatically --- src/main.ts | 2 +- src/vscode-button-group/index.ts | 1 + .../vscode-button-group.styles.ts} | 0 .../vscode-button-group.ts} | 12 ++++++------ src/vscode-split-button/index.ts | 1 - 5 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 src/vscode-button-group/index.ts rename src/{vscode-split-button/vscode-split-button.styles.ts => vscode-button-group/vscode-button-group.styles.ts} (100%) rename src/{vscode-split-button/vscode-split-button.ts => vscode-button-group/vscode-button-group.ts} (79%) delete mode 100644 src/vscode-split-button/index.ts diff --git a/src/main.ts b/src/main.ts index 21b3ac1a4..880d8a69f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,6 @@ export {VscodeBadge} from './vscode-badge/index.js'; export {VscodeButton} from './vscode-button/index.js'; +export {VscodeButtonGroup} from './vscode-button-group/index.js'; export {VscodeCheckbox} from './vscode-checkbox/index.js'; export {VscodeCheckboxGroup} from './vscode-checkbox-group/index.js'; export {VscodeCollapsible} from './vscode-collapsible/index.js'; @@ -18,7 +19,6 @@ export {VscodeRadio} from './vscode-radio/index.js'; export {VscodeRadioGroup} from './vscode-radio-group/index.js'; export {VscodeSingleSelect} from './vscode-single-select/index.js'; export {VscodeScrollable} from './vscode-scrollable/index.js'; -export {VscodeSplitButton} from './vscode-split-button/index.js'; export {VscodeSplitLayout} from './vscode-split-layout/index.js'; export {VscodeTabHeader} from './vscode-tab-header/index.js'; export {VscodeTabPanel} from './vscode-tab-panel/index.js'; diff --git a/src/vscode-button-group/index.ts b/src/vscode-button-group/index.ts new file mode 100644 index 000000000..1ab1b6730 --- /dev/null +++ b/src/vscode-button-group/index.ts @@ -0,0 +1 @@ +export {VscodeButtonGroup} from './vscode-button-group.js'; diff --git a/src/vscode-split-button/vscode-split-button.styles.ts b/src/vscode-button-group/vscode-button-group.styles.ts similarity index 100% rename from src/vscode-split-button/vscode-split-button.styles.ts rename to src/vscode-button-group/vscode-button-group.styles.ts diff --git a/src/vscode-split-button/vscode-split-button.ts b/src/vscode-button-group/vscode-button-group.ts similarity index 79% rename from src/vscode-split-button/vscode-split-button.ts rename to src/vscode-button-group/vscode-button-group.ts index 2b7883f39..ef0eeb248 100644 --- a/src/vscode-split-button/vscode-split-button.ts +++ b/src/vscode-button-group/vscode-button-group.ts @@ -1,12 +1,12 @@ import {html, TemplateResult} from 'lit'; -import {customElement, property} from 'lit/decorators.js'; +import {customElement} from 'lit/decorators.js'; import {VscElement} from '../includes/VscElement.js'; -import styles from './vscode-split-button.styles.js'; +import styles from './vscode-button-group.styles.js'; /** * Shows a split button, including several components in a single button. Commonly used to show a button with a dropdown to the right. * - * @tag vscode-split-button + * @tag vscode-button-group * * @cssprop [--vscode-button-background=#0078d4] * @cssprop [--vscode-button-foreground=#ffffff] @@ -20,8 +20,8 @@ import styles from './vscode-split-button.styles.js'; * @cssprop [--vscode-button-secondaryHoverBackground=#3c3c3c] * @cssprop [--vscode-focusBorder=#0078d4] */ -@customElement('vscode-split-button') -export class VscodeSplitButton extends VscElement { +@customElement('vscode-button-group') +export class VscodeButtonGroup extends VscElement { static override styles = styles; override render(): TemplateResult { @@ -31,6 +31,6 @@ export class VscodeSplitButton extends VscElement { declare global { interface HTMLElementTagNameMap { - 'vscode-split-button': VscodeSplitButton; + 'vscode-button-group': VscodeButtonGroup; } } diff --git a/src/vscode-split-button/index.ts b/src/vscode-split-button/index.ts deleted file mode 100644 index 61908b88e..000000000 --- a/src/vscode-split-button/index.ts +++ /dev/null @@ -1 +0,0 @@ -export {VscodeSplitButton} from './vscode-split-button.js'; From 0c37c57f83558c44ff166fa0bb3d051c69ef44f1 Mon Sep 17 00:00:00 2001 From: Anthony Stewart <150152+a-stewart@users.noreply.github.com> Date: Thu, 15 May 2025 20:55:29 +0200 Subject: [PATCH 04/10] Add a demo for to dev --- dev/vscode-button-group.html | 47 +++++++++++++++++++ .../vscode-button-group.styles.ts | 5 +- 2 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 dev/vscode-button-group.html diff --git a/dev/vscode-button-group.html b/dev/vscode-button-group.html new file mode 100644 index 000000000..41e126c1b --- /dev/null +++ b/dev/vscode-button-group.html @@ -0,0 +1,47 @@ + + + + + + <vscode-button-group> Demo + + + + + + + +
+

Basic example

+ + + + Hello World + + + + + Left + + Right + + + + Primary + Secondary + + +
+ + diff --git a/src/vscode-button-group/vscode-button-group.styles.ts b/src/vscode-button-group/vscode-button-group.styles.ts index 2eeb0aa71..8370b7685 100644 --- a/src/vscode-button-group/vscode-button-group.styles.ts +++ b/src/vscode-button-group/vscode-button-group.styles.ts @@ -1,9 +1,6 @@ import {css, CSSResultGroup} from 'lit'; import defaultStyles from '../includes/default.styles.js'; -import {getDefaultFontStack} from '../includes/helpers.js'; - -const defaultFontStack = getDefaultFontStack(); const styles: CSSResultGroup = [ defaultStyles, @@ -29,4 +26,4 @@ const styles: CSSResultGroup = [ `, ]; -export default styles; \ No newline at end of file +export default styles; From d6f485ca5861bda479e7b53b2c4f331a4e92dbea Mon Sep 17 00:00:00 2001 From: bendera Date: Thu, 15 May 2025 22:27:41 +0200 Subject: [PATCH 05/10] Prettier fix --- dev/vscode-button-group.html | 8 ++++---- src/vscode-button/vscode-button.styles.ts | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dev/vscode-button-group.html b/dev/vscode-button-group.html index 41e126c1b..c4d95fc3c 100644 --- a/dev/vscode-button-group.html +++ b/dev/vscode-button-group.html @@ -1,14 +1,14 @@ - + - - + + <vscode-button-group> Demo + >