Skip to content
61 changes: 61 additions & 0 deletions dev/vscode-button-group.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>&lt;vscode-button-group&gt; Demo</title>
<link
rel="stylesheet"
href="../node_modules/@vscode/codicons/dist/codicon.css"
id="vscode-codicon-stylesheet"
>
<script
type="module"
src="/node_modules/@vscode-elements/webview-playground/dist/index.js"
></script>
<script type="module" src="../dist/vscode-button/index.js"></script>
<script type="module" src="../dist/vscode-button-group/index.js"></script>
</head>

<body class="vscode-light">
<main>
<h2>Basic example</h2>

<vscode-demo>
<p>
<vscode-button-group>
<vscode-button secondary id="button-1">Hello World</vscode-button>
<vscode-button
secondary
icon="chevron-down"
id="button-2"
></vscode-button>
</vscode-button-group>
</p>

<p>
<vscode-button-group>
<vscode-button secondary>Left</vscode-button>
<vscode-button secondary icon="arrow-swap"></vscode-button>
<vscode-button secondary>Right</vscode-button>
</vscode-button-group>
</p>

<p>
<vscode-button-group>
<vscode-button>Left</vscode-button>
<vscode-button icon="arrow-swap"></vscode-button>
<vscode-button>Right</vscode-button>
</vscode-button-group>
</p>

<p>
<vscode-button-group>
<vscode-button>Primary</vscode-button>
<vscode-button secondary>Secondary</vscode-button>
</vscode-button-group>
</p>
</vscode-demo>
</main>
</body>
</html>
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
1 change: 1 addition & 0 deletions src/vscode-button-group/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {VscodeButtonGroup} from './vscode-button-group.js';
35 changes: 35 additions & 0 deletions src/vscode-button-group/vscode-button-group.styles.ts
Original file line number Diff line number Diff line change
@@ -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;
36 changes: 36 additions & 0 deletions src/vscode-button-group/vscode-button-group.ts
Original file line number Diff line number Diff line change
@@ -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` <slot></slot> `;
}
}

declare global {
interface HTMLElementTagNameMap {
'vscode-button-group': VscodeButtonGroup;
}
}
51 changes: 45 additions & 6 deletions src/vscode-button/vscode-button.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -91,6 +91,10 @@ const styles: CSSResultGroup = [
margin-left: 0;
}

::slotted(*:last-child) {
margin-right: 0;
}

::slotted(vscode-icon) {
color: inherit;
}
Expand All @@ -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 {
Expand All @@ -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;
}
`,
];

Expand Down
24 changes: 24 additions & 0 deletions src/vscode-button/vscode-button.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ describe('vscode-button', () => {
<vscode-icon name="account" class="icon"></vscode-icon>
<slot></slot>
</span>
<div class="divider">
<div>
</div>
</div>
`
);
});
Expand All @@ -95,6 +99,10 @@ describe('vscode-button', () => {
<vscode-icon name="account" spin class="icon"></vscode-icon>
<slot></slot>
</span>
<div class="divider">
<div>
</div>
</div>
`
);
});
Expand All @@ -113,6 +121,10 @@ describe('vscode-button', () => {
<vscode-icon name="account" class="icon" spin-duration="5"></vscode-icon>
<slot></slot>
</span>
<div class="divider">
<div>
</div>
</div>
`
);
});
Expand All @@ -128,6 +140,10 @@ describe('vscode-button', () => {
<slot></slot>
<vscode-icon name="account" class="icon-after"></vscode-icon>
</span>
<div class="divider">
<div>
</div>
</div>
`
);
});
Expand All @@ -143,6 +159,10 @@ describe('vscode-button', () => {
<slot></slot>
<vscode-icon name="account" class="icon-after" spin></vscode-icon>
</span>
<div class="divider">
<div>
</div>
</div>
`
);
});
Expand All @@ -161,6 +181,10 @@ describe('vscode-button', () => {
<slot></slot>
<vscode-icon name="account" class="icon-after" spin-duration="5"></vscode-icon>
</span>
<div class="divider">
<div>
</div>
</div>
`
);
});
Expand Down
1 change: 1 addition & 0 deletions src/vscode-button/vscode-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ export class VscodeButton extends VscElement {
<slot></slot>
${iconAfterElem}
</span>
<div class="divider"><div></div></div>
`;
}
}
Expand Down