Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

### Added

- **Button**: Add the ability to modify the icon animation parameters.
- **Button**: Align and arrange any content added through the main slot.

## [1.6.2] - 2024-10-07

### Fixed
Expand Down
100 changes: 69 additions & 31 deletions dev/vscode-button.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,81 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>&lt;vscode-button&gt; Demo</title>
<link rel="stylesheet" href="../dev-assets/default-webview-styles.css" />
<link rel="stylesheet" href="../node_modules/@vscode/codicons/dist/codicon.css" id="vscode-codicon-stylesheet" />
<script type="module" src="../dev-assets/component-preview.js"></script>
<script type="module" src="/node_modules/@vscode-elements/webview-playground/dist/index.js"></script>
<script type="module" src="../dist/vscode-button/index.js"></script>
</head>

<body class="vscode-light">
<main>
<div class="story">
<h2 class="story-title">Basic example</h2>
<div class="story-content">
<component-preview>
<vscode-button id="button-1" autofocus>Enabled</vscode-button>
<vscode-button secondary id="button-2" vsc-cloak>Hello World</vscode-button>
<vscode-button id="button-4" disabled vsc-cloak>Disabled</vscode-button>
<vscode-button id="button-5" disabled secondary vsc-cloak>Disabled</vscode-button>
<vscode-button icon="account" iconafter="chevron-right" vsc-cloak>Icons</vscode-button>
<vscode-button id="button-1" vsc-cloak icon="check" style="width: 300px">Commit</vscode-button>
</component-preview>
<button id="bt-focus" type="button">Focus first button</button>
<script>
const bt1 = document.querySelector('#button-1');
const bt4 = document.querySelector('#button-4');
const btFocus = document.querySelector('#bt-focus');

const listener = (event) => {
console.log(event);
};

bt1.addEventListener('vsc-click', listener);
bt4.addEventListener('vsc-click', listener);
btFocus.addEventListener('click', () => {
bt1.focus();
});
</script>
</div>
</div>
<h2>Basic example</h2>

<vscode-demo>
<vscode-button id="button-1" autofocus>Enabled</vscode-button>
<vscode-button secondary id="button-2" vsc-cloak>Hello World</vscode-button>
<vscode-button id="button-4" disabled vsc-cloak>Disabled</vscode-button>
<vscode-button id="button-5" disabled secondary vsc-cloak>Disabled</vscode-button>
<vscode-button icon="account" iconafter="chevron-right" vsc-cloak>Icons</vscode-button>
<vscode-button id="button-1" vsc-cloak icon="check" style="width: 300px">Commit</vscode-button>
<button id="bt-focus" type="button">Focus first button</button>
<script>
const bt1 = document.querySelector('#button-1');
const bt4 = document.querySelector('#button-4');
const btFocus = document.querySelector('#bt-focus');

const listener = (event) => {
console.log(event);
};

bt1.addEventListener('vsc-click', listener);
bt4.addEventListener('vsc-click', listener);
btFocus.addEventListener('click', () => {
bt1.focus();
});
</script>
</vscode-demo>

<h2>Rich content</h2>
<vscode-demo>
<style>
vscode-button .red,
vscode-button .green,
vscode-button .blue {
background-color: red;
border-radius: 100%;
display: inline-block;
height: 12px;
width: 12px;
}

vscode-button .red {
background-color: red;
}

vscode-button .green {
background-color: green;
}

vscode-button .blue {
background-color: blue;
}
</style>
<vscode-button secondary>
<span class="red"></span>Red
</vscode-button>
<vscode-button secondary>
<span class="green"></span>Green
</vscode-button>
<vscode-button secondary>
<span class="blue"></span>Blue
</vscode-button>
<vscode-button>
<vscode-icon spin spin-duration="1" name="sync" aria-hidden="true"></vscode-icon>
Loading
</vscode-button>
<vscode-button icon="sync" icon-spin icon-spin-duration="2">Sync</vscode-button>
</vscode-demo>

</main>
</body>

Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
"@types/node": "^22.6.1",
"@typescript-eslint/eslint-plugin": "^8.7.0",
"@typescript-eslint/parser": "^8.7.0",
"@vscode-elements/webview-playground": "^1.1.1",
"@vscode-elements/webview-playground": "^1.1.2",
"@vscode/codicons": "^0.0.36",
"@web/dev-server": "^0.4.6",
"@web/dev-server-esbuild": "^1.0.2",
Expand Down
19 changes: 17 additions & 2 deletions src/vscode-button/vscode-button.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const styles: CSSResultGroup = [
defaultStyles,
css`
:host {
align-items: center;
background-color: var(--vscode-button-background);
border-color: var(--vscode-button-border, var(--vscode-button-background));
border-style: solid;
Expand Down Expand Up @@ -76,6 +75,20 @@ const styles: CSSResultGroup = [
background-color: var(--vscode-button-secondaryBackground);
}

::slotted(*) {
display: inline-block;
margin-left: 4px;
margin-right: 4px;
}

::slotted(*:first-child) {
margin-left: 0;
}

::slotted(vscode-icon) {
color: inherit;
}

.wrapper {
align-items: center;
box-sizing: border-box;
Expand All @@ -86,7 +99,9 @@ const styles: CSSResultGroup = [
}

slot {
display: block;
align-items: center;
display: flex;
height: 100%;
}

.icon {
Expand Down
38 changes: 37 additions & 1 deletion src/vscode-button/vscode-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {classMap} from 'lit/directives/class-map.js';
import {VscElement} from '../includes/VscElement.js';
import '../vscode-icon/index.js';
import styles from './vscode-button.styles.js';
import {ifDefined} from 'lit/directives/if-defined.js';

/**
* @fires vsc-click Dispatched only when button is not in disabled state.
Expand Down Expand Up @@ -53,12 +54,40 @@ export class VscodeButton extends VscElement {
@property()
icon = '';

/**
* Spin property for the icon
*/
@property({type: Boolean, reflect: true, attribute: 'icon-spin'})
iconSpin? = false;

/**
* Duration property for the icon
*/
@property({type: Number, reflect: true, attribute: 'icon-spin-duration'})
iconSpinDuration?: number;

/**
* A [Codicon](https://microsoft.github.io/vscode-codicons/dist/codicon.html) after the label
*/
@property({attribute: 'icon-after'})
iconAfter = '';

/**
* Spin property for the after icon
*/
@property({type: Boolean, reflect: true, attribute: 'icon-after-spin'})
iconAfterSpin = false;

/**
* Duration property for the after icon
*/
@property({
type: Number,
reflect: true,
attribute: 'icon-after-spin-duration',
})
iconAfterSpinDuration?: number;

@property({type: Boolean, reflect: true})
focused = false;

Expand Down Expand Up @@ -196,12 +225,19 @@ export class VscodeButton extends VscElement {
};

const iconElem = hasIcon
? html`<vscode-icon name="${this.icon}" class="icon"></vscode-icon>`
? html`<vscode-icon
name="${this.icon}"
?spin="${this.iconSpin}"
spin-duration="${ifDefined(this.iconSpinDuration)}"
class="icon"
></vscode-icon>`
: nothing;

const iconAfterElem = hasIconAfter
? html`<vscode-icon
name="${this.iconAfter}"
?spin="${this.iconAfterSpin}"
spin-duration="${ifDefined(this.iconAfterSpinDuration)}"
class="icon-after"
></vscode-icon>`
: nothing;
Expand Down