diff --git a/dev/vscode-button-group.html b/dev/vscode-button-group.html new file mode 100644 index 000000000..0913083f9 --- /dev/null +++ b/dev/vscode-button-group.html @@ -0,0 +1,61 @@ + + + + + + <vscode-button-group> Demo + + + + + + + +
+

Basic example

+ + +

+ + Hello World + + +

+ +

+ + Left + + Right + +

+ +

+ + Left + + Right + +

+ +

+ + Primary + Secondary + +

+
+
+ + diff --git a/src/main.ts b/src/main.ts index 1e11e818e..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'; 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-button-group/vscode-button-group.styles.ts b/src/vscode-button-group/vscode-button-group.styles.ts new file mode 100644 index 000000000..5b8e5191c --- /dev/null +++ b/src/vscode-button-group/vscode-button-group.styles.ts @@ -0,0 +1,35 @@ +import {css, CSSResultGroup} from 'lit'; + +import defaultStyles from '../includes/default.styles.js'; + +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)) { + --divider-display: block; + + border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-right-width: 0; + } + + ::slotted(vscode-button:focus) { + z-index: 1; + } + `, +]; + +export default styles; diff --git a/src/vscode-button-group/vscode-button-group.ts b/src/vscode-button-group/vscode-button-group.ts new file mode 100644 index 000000000..ef0eeb248 --- /dev/null +++ b/src/vscode-button-group/vscode-button-group.ts @@ -0,0 +1,36 @@ +import {html, TemplateResult} from 'lit'; +import {customElement} from 'lit/decorators.js'; +import {VscElement} from '../includes/VscElement.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-button-group + * + * @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-button-group') +export class VscodeButtonGroup extends VscElement { + static override styles = styles; + + override render(): TemplateResult { + return html` `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'vscode-button-group': VscodeButtonGroup; + } +} diff --git a/src/vscode-button/vscode-button.styles.ts b/src/vscode-button/vscode-button.styles.ts index 78da388e7..3dfb0bb86 100644 --- a/src/vscode-button/vscode-button.styles.ts +++ b/src/vscode-button/vscode-button.styles.ts @@ -15,13 +15,13 @@ 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; } @@ -91,6 +91,10 @@ const styles: CSSResultGroup = [ margin-left: 0; } + ::slotted(*:last-child) { + margin-right: 0; + } + ::slotted(vscode-icon) { color: inherit; } @@ -102,6 +106,12 @@ const styles: CSSResultGroup = [ justify-content: center; position: relative; width: 100%; + height: 100%; + padding: 1px 13px; + } + + :host(:empty) .wrapper { + padding: 1px 5px; } slot { @@ -110,17 +120,46 @@ 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; } + + .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, + rgba(255, 255, 255, 0.4) + ); + height: 100%; + width: 1px; + margin: 0; + } + + :host([secondary]) .divider > div { + background-color: var(--vscode-button-secondaryForeground, #cccccc); + opacity: 0.4; + } `, ]; diff --git a/src/vscode-button/vscode-button.test.ts b/src/vscode-button/vscode-button.test.ts index d7577d679..6ec3efa3c 100644 --- a/src/vscode-button/vscode-button.test.ts +++ b/src/vscode-button/vscode-button.test.ts @@ -80,6 +80,10 @@ describe('vscode-button', () => { +
+
+
+
` ); }); @@ -95,6 +99,10 @@ describe('vscode-button', () => { +
+
+
+
` ); }); @@ -113,6 +121,10 @@ describe('vscode-button', () => { +
+
+
+
` ); }); @@ -128,6 +140,10 @@ describe('vscode-button', () => { +
+
+
+
` ); }); @@ -143,6 +159,10 @@ describe('vscode-button', () => { +
+
+
+
` ); }); @@ -161,6 +181,10 @@ describe('vscode-button', () => { +
+
+
+
` ); }); 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} +
`; } }