From 47d9dc24029dd8a24742a85f3574d63e46a1199b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 29 Aug 2026 02:28:56 +0000
Subject: [PATCH 01/31] feat: add size property (small/medium/large) to
vscode-form-group
Co-authored-by: 171h <40647432+171h@users.noreply.github.com>
---
.../vscode-form-group.styles.ts | 21 +++++++++++++
.../vscode-form-group.test.ts | 30 ++++++++++++++++++-
src/vscode-form-group/vscode-form-group.ts | 8 +++++
3 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/src/vscode-form-group/vscode-form-group.styles.ts b/src/vscode-form-group/vscode-form-group.styles.ts
index 9a062fb13..b58ea06a0 100644
--- a/src/vscode-form-group/vscode-form-group.styles.ts
+++ b/src/vscode-form-group/vscode-form-group.styles.ts
@@ -12,6 +12,27 @@ const styles: CSSResultGroup = [
margin: 15px 0;
}
+ :host([size='small']) {
+ --label-right-margin: 10px;
+ --label-width: 100px;
+
+ margin: 8px 0;
+ }
+
+ :host([size='medium']) {
+ --label-right-margin: 14px;
+ --label-width: 150px;
+
+ margin: 15px 0;
+ }
+
+ :host([size='large']) {
+ --label-right-margin: 18px;
+ --label-width: 200px;
+
+ margin: 22px 0;
+ }
+
:host([variant='settings-group']) {
margin: 0;
padding: 12px 14px 18px;
diff --git a/src/vscode-form-group/vscode-form-group.test.ts b/src/vscode-form-group/vscode-form-group.test.ts
index 186c551f1..9b041ee2d 100644
--- a/src/vscode-form-group/vscode-form-group.test.ts
+++ b/src/vscode-form-group/vscode-form-group.test.ts
@@ -1,9 +1,37 @@
import {VscodeFormGroup} from './index.js';
-import {expect} from '@open-wc/testing';
+import {expect, fixture, html} from '@open-wc/testing';
describe('vscode-form-group', () => {
it('is defined', () => {
const el = document.createElement('vscode-form-group');
expect(el).to.instanceOf(VscodeFormGroup);
});
+
+ it('uses medium size by default', async () => {
+ const el = await fixture(
+ html``
+ );
+
+ expect(el.size).to.eq('medium');
+ expect(el.getAttribute('size')).to.eq('medium');
+ });
+
+ it('sets the size attribute', async () => {
+ const el = await fixture(
+ html``
+ );
+
+ expect(el.size).to.eq('small');
+ });
+
+ it('reflects the size property', async () => {
+ const el = await fixture(
+ html``
+ );
+
+ el.size = 'large';
+ await el.updateComplete;
+
+ expect(el.getAttribute('size')).to.eq('large');
+ });
});
diff --git a/src/vscode-form-group/vscode-form-group.ts b/src/vscode-form-group/vscode-form-group.ts
index 0033d3647..edfcef554 100644
--- a/src/vscode-form-group/vscode-form-group.ts
+++ b/src/vscode-form-group/vscode-form-group.ts
@@ -5,6 +5,8 @@ import styles from './vscode-form-group.styles.js';
export type FormGroupVariant = 'horizontal' | 'vertical' | 'settings-group';
+export type FormGroupSize = 'small' | 'medium' | 'large';
+
/**
* @tag vscode-form-group
*
@@ -18,6 +20,12 @@ export class VscodeFormGroup extends VscElement {
@property({reflect: true})
variant: FormGroupVariant = 'horizontal';
+ /**
+ * The size of the form group. The `medium` size is the default.
+ */
+ @property({reflect: true})
+ size: FormGroupSize = 'medium';
+
override render(): TemplateResult {
return html`
From b755d9f5bd7a02cc4e3626ea340eae26a5754a8d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 29 Aug 2026 02:29:38 +0000
Subject: [PATCH 02/31] refactor: remove redundant base margin from
vscode-form-group styles
Co-authored-by: 171h <40647432+171h@users.noreply.github.com>
---
src/vscode-form-group/vscode-form-group.styles.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/vscode-form-group/vscode-form-group.styles.ts b/src/vscode-form-group/vscode-form-group.styles.ts
index b58ea06a0..c6902b68c 100644
--- a/src/vscode-form-group/vscode-form-group.styles.ts
+++ b/src/vscode-form-group/vscode-form-group.styles.ts
@@ -9,7 +9,6 @@ const styles: CSSResultGroup = [
--label-width: 150px;
display: block;
- margin: 15px 0;
}
:host([size='small']) {
From 50d01b564ca140bf238a61f1caa6083c5b1f6a9b Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 29 Aug 2026 02:43:08 +0000
Subject: [PATCH 03/31] feat: add size property to all form control components
Co-authored-by: 171h <40647432+171h@users.noreply.github.com>
---
.../FormButtonWidgetBase.ts | 7 +++++
.../form-button-widget/base.styles.ts | 31 ++++++++++++++++++-
src/includes/form-control-size.ts | 5 +++
src/includes/vscode-select/styles.ts | 29 ++++++++++++++++-
.../vscode-select/vscode-select-base.ts | 7 +++++
src/vscode-button/vscode-button.styles.ts | 25 ++++++++++++++-
src/vscode-button/vscode-button.test.ts | 19 ++++++++++++
src/vscode-button/vscode-button.ts | 8 +++++
src/vscode-checkbox/vscode-checkbox.test.ts | 19 ++++++++++++
.../vscode-form-group.styles.ts | 2 ++
src/vscode-form-group/vscode-form-group.ts | 4 ++-
.../vscode-multi-select.test.ts | 19 ++++++++++++
src/vscode-radio/vscode-radio.test.ts | 15 +++++++++
.../vscode-single-select.test.ts | 19 ++++++++++++
src/vscode-textarea/vscode-textarea.styles.ts | 13 +++++++-
src/vscode-textarea/vscode-textarea.test.ts | 19 ++++++++++++
src/vscode-textarea/vscode-textarea.ts | 8 +++++
.../vscode-textfield.styles.ts | 23 +++++++++++++-
src/vscode-textfield/vscode-textfield.test.ts | 19 ++++++++++++
src/vscode-textfield/vscode-textfield.ts | 8 +++++
20 files changed, 293 insertions(+), 6 deletions(-)
create mode 100644 src/includes/form-control-size.ts
diff --git a/src/includes/form-button-widget/FormButtonWidgetBase.ts b/src/includes/form-button-widget/FormButtonWidgetBase.ts
index 232795ded..f8e9bfddb 100644
--- a/src/includes/form-button-widget/FormButtonWidgetBase.ts
+++ b/src/includes/form-button-widget/FormButtonWidgetBase.ts
@@ -1,10 +1,17 @@
import {property} from 'lit/decorators.js';
import {VscElement} from '../VscElement.js';
+import {FormControlSize} from '../form-control-size.js';
export class FormButtonWidgetBase extends VscElement {
@property({type: Boolean, reflect: true})
focused = false;
+ /**
+ * The size of the component. The `medium` size is the default.
+ */
+ @property({reflect: true})
+ size: FormControlSize = 'medium';
+
constructor() {
super();
}
diff --git a/src/includes/form-button-widget/base.styles.ts b/src/includes/form-button-widget/base.styles.ts
index 5fc6e7762..29e4c903d 100644
--- a/src/includes/form-button-widget/base.styles.ts
+++ b/src/includes/form-button-widget/base.styles.ts
@@ -19,7 +19,10 @@ export default [
cursor: pointer;
display: block;
font-family: var(--vscode-font-family, sans-serif);
- font-size: var(--vscode-font-size, 13px);
+ font-size: var(
+ --vsc-form-control-font-size,
+ var(--vscode-font-size, 13px)
+ );
font-weight: var(--vscode-font-weight, normal);
line-height: 18px;
margin-bottom: 4px;
@@ -29,6 +32,32 @@ export default [
user-select: none;
}
+ :host([size='small']) {
+ --vsc-form-control-font-size: 12px;
+ }
+
+ :host([size='large']) {
+ --vsc-form-control-font-size: 15px;
+ }
+
+ :host([size='small']) .icon {
+ height: 16px;
+ width: 16px;
+ }
+
+ :host([size='large']) .icon {
+ height: 20px;
+ width: 20px;
+ }
+
+ :host([size='small']) .label-inner {
+ padding-left: 25px;
+ }
+
+ :host([size='large']) .label-inner {
+ padding-left: 29px;
+ }
+
:host([disabled]) .wrapper {
cursor: default;
}
diff --git a/src/includes/form-control-size.ts b/src/includes/form-control-size.ts
new file mode 100644
index 000000000..53e08ea5d
--- /dev/null
+++ b/src/includes/form-control-size.ts
@@ -0,0 +1,5 @@
+/**
+ * Size options of the form control components. The `medium` size is the default and matches
+ * the regular VS Code sizing.
+ */
+export type FormControlSize = 'small' | 'medium' | 'large';
diff --git a/src/includes/vscode-select/styles.ts b/src/includes/vscode-select/styles.ts
index 1758d9f3a..cabe3ed75 100644
--- a/src/includes/vscode-select/styles.ts
+++ b/src/includes/vscode-select/styles.ts
@@ -12,6 +12,30 @@ export default [
width: 320px;
}
+ :host([size='small']) {
+ --vsc-form-control-font-size: 12px;
+ }
+
+ :host([size='large']) {
+ --vsc-form-control-font-size: 15px;
+ }
+
+ :host([size='small']) .select-face {
+ padding: 2px 4px;
+ }
+
+ :host([size='large']) .select-face {
+ padding: 4px 4px;
+ }
+
+ :host([size='small']) .combobox-input {
+ padding: 3px 4px;
+ }
+
+ :host([size='large']) .combobox-input {
+ padding: 5px 4px;
+ }
+
.main-slot {
display: none;
}
@@ -26,7 +50,10 @@ export default [
box-sizing: border-box;
color: var(--vscode-settings-dropdownForeground, #cccccc);
font-family: var(--vscode-font-family, sans-serif);
- font-size: var(--vscode-font-size, 13px);
+ font-size: var(
+ --vsc-form-control-font-size,
+ var(--vscode-font-size, 13px)
+ );
font-weight: var(--vscode-font-weight, normal);
line-height: 18px;
position: relative;
diff --git a/src/includes/vscode-select/vscode-select-base.ts b/src/includes/vscode-select/vscode-select-base.ts
index 66ce7ead0..3fe0e15b6 100644
--- a/src/includes/vscode-select/vscode-select-base.ts
+++ b/src/includes/vscode-select/vscode-select-base.ts
@@ -9,6 +9,7 @@ import '../../vscode-option/index.js';
import {VscodeOption} from '../../vscode-option/index.js';
import {stylePropertyMap} from '../style-property-map.js';
import {VscElement} from '../VscElement.js';
+import {FormControlSize} from '../form-control-size.js';
import {filterOptionsByPattern, highlightRanges} from './helpers.js';
import type {InternalOption, Option, FilterMethod} from './types.js';
import {OptionListController} from './OptionListController.js';
@@ -69,6 +70,12 @@ export class VscodeSelectBase extends VscElement {
@property({type: Boolean, reflect: true})
invalid = false;
+ /**
+ * The size of the component. The `medium` size is the default.
+ */
+ @property({reflect: true})
+ size: FormControlSize = 'medium';
+
/**
* Search method in the filtered list within the combobox mode.
*
diff --git a/src/vscode-button/vscode-button.styles.ts b/src/vscode-button/vscode-button.styles.ts
index a2e3c20c8..c0a9a0974 100644
--- a/src/vscode-button/vscode-button.styles.ts
+++ b/src/vscode-button/vscode-button.styles.ts
@@ -35,7 +35,10 @@ const styles: CSSResultGroup = [
color: var(--vscode-button-foreground, #ffffff);
display: flex;
font-family: var(--vscode-font-family, ${defaultFontStack});
- font-size: var(--vscode-font-size, 13px);
+ font-size: var(
+ --vsc-form-control-font-size,
+ var(--vscode-font-size, 13px)
+ );
font-weight: var(--vscode-font-weight, normal);
height: 100%;
justify-content: center;
@@ -49,6 +52,26 @@ const styles: CSSResultGroup = [
width: 100%;
}
+ :host([size='small']) {
+ --vsc-form-control-font-size: 12px;
+ }
+
+ :host([size='large']) {
+ --vsc-form-control-font-size: 15px;
+ }
+
+ :host([size='small']) .base {
+ line-height: 18px;
+ padding: 1px calc(9px + var(--vsc-base-additional-right-padding, 0px)) 1px
+ 9px;
+ }
+
+ :host([size='large']) .base {
+ line-height: 26px;
+ padding: 1px calc(17px + var(--vsc-base-additional-right-padding, 0px))
+ 1px 17px;
+ }
+
:host([block]) .base {
min-height: 28px;
text-align: center;
diff --git a/src/vscode-button/vscode-button.test.ts b/src/vscode-button/vscode-button.test.ts
index f79a0046e..869f6e9c8 100644
--- a/src/vscode-button/vscode-button.test.ts
+++ b/src/vscode-button/vscode-button.test.ts
@@ -24,6 +24,25 @@ describe('vscode-button', () => {
expect(el.focused).to.be.true;
});
+ it('uses medium size by default', async () => {
+ const el = await fixture
(
+ html`test`
+ );
+
+ expect(el.size).to.eq('medium');
+ expect(el.getAttribute('size')).to.eq('medium');
+ });
+
+ it('reflects the size property', async () => {
+ const el = await fixture(
+ html`test`
+ );
+ el.size = 'large';
+ await el.updateComplete;
+
+ expect(el.getAttribute('size')).to.eq('large');
+ });
+
it('dispatches click event when enter key is pressed', async () => {
const el = await fixture(
html`test`
diff --git a/src/vscode-button/vscode-button.ts b/src/vscode-button/vscode-button.ts
index 5730cc2a2..fd1356429 100644
--- a/src/vscode-button/vscode-button.ts
+++ b/src/vscode-button/vscode-button.ts
@@ -2,6 +2,7 @@ import {html, nothing, PropertyValueMap, TemplateResult} from 'lit';
import {property, state} from 'lit/decorators.js';
import {classMap} from 'lit/directives/class-map.js';
import {customElement, VscElement} from '../includes/VscElement.js';
+import {FormControlSize} from '../includes/form-control-size.js';
import '../vscode-icon/index.js';
import styles from './vscode-button.styles.js';
import {ifDefined} from 'lit/directives/if-defined.js';
@@ -22,6 +23,7 @@ import {ifDefined} from 'lit/directives/if-defined.js';
* @cssprop [--vscode-button-secondaryBackground=#313131]
* @cssprop [--vscode-button-secondaryHoverBackground=#3c3c3c]
* @cssprop [--vscode-focusBorder=#0078d4]
+ * @cssprop [--vsc-form-control-font-size=var(--vscode-font-size, 13px)] - Font size of the button label. It is set automatically by the `size` property.
*
* @csspart base - The main content area of the component.
*
@@ -62,6 +64,12 @@ export class VscodeButton extends VscElement {
@property({type: Boolean, reflect: true})
disabled = false;
+ /**
+ * The size of the button. The `medium` size is the default.
+ */
+ @property({reflect: true})
+ size: FormControlSize = 'medium';
+
/**
* A [Codicon](https://microsoft.github.io/vscode-codicons/dist/codicon.html) before the label
*/
diff --git a/src/vscode-checkbox/vscode-checkbox.test.ts b/src/vscode-checkbox/vscode-checkbox.test.ts
index 7653d5333..30c995221 100644
--- a/src/vscode-checkbox/vscode-checkbox.test.ts
+++ b/src/vscode-checkbox/vscode-checkbox.test.ts
@@ -24,6 +24,25 @@ describe('vscode-checkbox', () => {
expect(el.type).to.eq('checkbox');
});
+ it('uses medium size by default', async () => {
+ const el = await fixture(
+ html`Test checkbox`
+ );
+
+ expect(el.size).to.eq('medium');
+ expect(el.getAttribute('size')).to.eq('medium');
+ });
+
+ it('reflects the size property', async () => {
+ const el = await fixture(
+ html`Test checkbox`
+ );
+ el.size = 'small';
+ await el.updateComplete;
+
+ expect(el.getAttribute('size')).to.eq('small');
+ });
+
it('should be participated in the form', async () => {
const form = document.createElement('form');
await fixture(
diff --git a/src/vscode-form-group/vscode-form-group.styles.ts b/src/vscode-form-group/vscode-form-group.styles.ts
index c6902b68c..741aa658d 100644
--- a/src/vscode-form-group/vscode-form-group.styles.ts
+++ b/src/vscode-form-group/vscode-form-group.styles.ts
@@ -14,6 +14,7 @@ const styles: CSSResultGroup = [
:host([size='small']) {
--label-right-margin: 10px;
--label-width: 100px;
+ --vsc-form-control-font-size: 12px;
margin: 8px 0;
}
@@ -28,6 +29,7 @@ const styles: CSSResultGroup = [
:host([size='large']) {
--label-right-margin: 18px;
--label-width: 200px;
+ --vsc-form-control-font-size: 15px;
margin: 22px 0;
}
diff --git a/src/vscode-form-group/vscode-form-group.ts b/src/vscode-form-group/vscode-form-group.ts
index edfcef554..3135a173b 100644
--- a/src/vscode-form-group/vscode-form-group.ts
+++ b/src/vscode-form-group/vscode-form-group.ts
@@ -1,17 +1,19 @@
import {html, TemplateResult} from 'lit';
import {property} from 'lit/decorators.js';
import {customElement, VscElement} from '../includes/VscElement.js';
+import {FormControlSize} from '../includes/form-control-size.js';
import styles from './vscode-form-group.styles.js';
export type FormGroupVariant = 'horizontal' | 'vertical' | 'settings-group';
-export type FormGroupSize = 'small' | 'medium' | 'large';
+export type FormGroupSize = FormControlSize;
/**
* @tag vscode-form-group
*
* @cssprop [--label-width=150px] - The width of the label in horizontal mode
* @cssprop [--label-right-margin=14px] - The right margin of the label in horizontal mode
+ * @cssprop [--vsc-form-control-font-size] - Font size of the slotted form controls. It is set automatically by the `size` property.
*/
@customElement('vscode-form-group')
export class VscodeFormGroup extends VscElement {
diff --git a/src/vscode-multi-select/vscode-multi-select.test.ts b/src/vscode-multi-select/vscode-multi-select.test.ts
index fa96eb3bc..c5ec605cc 100644
--- a/src/vscode-multi-select/vscode-multi-select.test.ts
+++ b/src/vscode-multi-select/vscode-multi-select.test.ts
@@ -13,6 +13,25 @@ describe('vscode-multi-select', () => {
expect(el).to.instanceOf(VscodeMultiSelect);
});
+ it('uses medium size by default', async () => {
+ const el = (await fixture(html`
+
+ `)) as VscodeMultiSelect;
+
+ expect(el.size).to.eq('medium');
+ expect(el.getAttribute('size')).to.eq('medium');
+ });
+
+ it('reflects the size property', async () => {
+ const el = (await fixture(html`
+
+ `)) as VscodeMultiSelect;
+ el.size = 'large';
+ await el.updateComplete;
+
+ expect(el.getAttribute('size')).to.eq('large');
+ });
+
it('should display selected value', async () => {
const el = (await fixture(html`
diff --git a/src/vscode-radio/vscode-radio.test.ts b/src/vscode-radio/vscode-radio.test.ts
index c4da222f1..9890d9c8f 100644
--- a/src/vscode-radio/vscode-radio.test.ts
+++ b/src/vscode-radio/vscode-radio.test.ts
@@ -31,6 +31,21 @@ describe('vscode-radio', () => {
expect(radio.form?.getAttribute('id')).to.eq('test-form');
});
+ it('uses medium size by default', async () => {
+ const el = await fixture(html``);
+
+ expect(el.size).to.eq('medium');
+ expect(el.getAttribute('size')).to.eq('medium');
+ });
+
+ it('reflects the size property', async () => {
+ const el = await fixture(html``);
+ el.size = 'large';
+ await el.updateComplete;
+
+ expect(el.getAttribute('size')).to.eq('large');
+ });
+
it('type should be "radio"', async () => {
const el = await fixture(html``);
diff --git a/src/vscode-single-select/vscode-single-select.test.ts b/src/vscode-single-select/vscode-single-select.test.ts
index f61c2643f..fc046b82d 100644
--- a/src/vscode-single-select/vscode-single-select.test.ts
+++ b/src/vscode-single-select/vscode-single-select.test.ts
@@ -29,6 +29,25 @@ describe('vscode-single-select', () => {
expect(el).to.instanceOf(VscodeSingleSelect);
});
+ it('uses medium size by default', async () => {
+ const el = (await fixture(html`
+
+ `)) as VscodeSingleSelect;
+
+ expect(el.size).to.eq('medium');
+ expect(el.getAttribute('size')).to.eq('medium');
+ });
+
+ it('reflects the size property', async () => {
+ const el = (await fixture(html`
+
+ `)) as VscodeSingleSelect;
+ el.size = 'small';
+ await el.updateComplete;
+
+ expect(el.getAttribute('size')).to.eq('small');
+ });
+
describe('select mode', () => {
it('should display selected value', async () => {
const el = (await fixture(html`
diff --git a/src/vscode-textarea/vscode-textarea.styles.ts b/src/vscode-textarea/vscode-textarea.styles.ts
index 76a15e00a..4791954ac 100644
--- a/src/vscode-textarea/vscode-textarea.styles.ts
+++ b/src/vscode-textarea/vscode-textarea.styles.ts
@@ -19,6 +19,14 @@ const styles: CSSResultGroup = [
height: auto;
}
+ :host([size='small']) {
+ --vsc-form-control-font-size: 12px;
+ }
+
+ :host([size='large']) {
+ --vsc-form-control-font-size: 15px;
+ }
+
.shadow {
box-shadow: var(--vscode-scrollbar-shadow, #000000) 0 6px 6px -6px inset;
display: none;
@@ -43,7 +51,10 @@ const styles: CSSResultGroup = [
color: var(--vscode-settings-textInputForeground, #cccccc);
display: block;
font-family: var(--vscode-font-family, sans-serif);
- font-size: var(--vscode-font-size, 13px);
+ font-size: var(
+ --vsc-form-control-font-size,
+ var(--vscode-font-size, 13px)
+ );
font-weight: var(--vscode-font-weight, normal);
height: 100%;
width: 100%;
diff --git a/src/vscode-textarea/vscode-textarea.test.ts b/src/vscode-textarea/vscode-textarea.test.ts
index a5ee6fe3f..d112fd020 100644
--- a/src/vscode-textarea/vscode-textarea.test.ts
+++ b/src/vscode-textarea/vscode-textarea.test.ts
@@ -38,6 +38,25 @@ describe('vscode-textarea', () => {
`);
});
+ it('uses medium size by default', async () => {
+ const el = await fixture(
+ html``
+ );
+
+ expect(el.size).to.eq('medium');
+ expect(el.getAttribute('size')).to.eq('medium');
+ });
+
+ it('reflects the size property', async () => {
+ const el = await fixture(
+ html``
+ );
+ el.size = 'large';
+ await el.updateComplete;
+
+ expect(el.getAttribute('size')).to.eq('large');
+ });
+
it('should forward "autocomplete" attribute to the inner textarea', async () => {
const el = await fixture(
html``
diff --git a/src/vscode-textarea/vscode-textarea.ts b/src/vscode-textarea/vscode-textarea.ts
index 3d6eea849..b577c4613 100644
--- a/src/vscode-textarea/vscode-textarea.ts
+++ b/src/vscode-textarea/vscode-textarea.ts
@@ -3,6 +3,7 @@ import {property, query, state} from 'lit/decorators.js';
import {ifDefined} from 'lit/directives/if-defined.js';
import {classMap} from 'lit/directives/class-map.js';
import {customElement, VscElement} from '../includes/VscElement.js';
+import {FormControlSize} from '../includes/form-control-size.js';
import {stylePropertyMap} from '../includes/style-property-map.js';
import {AssociatedFormControl} from '../includes/AssociatedFormControl.js';
import styles from './vscode-textarea.styles.js';
@@ -36,6 +37,7 @@ import styles from './vscode-textarea.styles.js';
* @cssprop [--vscode-scrollbarSlider-background=rgba(121, 121, 121, 0.4)]
* @cssprop [--vscode-scrollbarSlider-hoverBackground=rgba(100, 100, 100, 0.7)]
* @cssprop [--vscode-scrollbarSlider-activeBackground=rgba(191, 191, 191, 0.4)]
+ * @cssprop [--vsc-form-control-font-size=var(--vscode-font-size, 13px)] - Font size of the textarea. It is set automatically by the `size` property.
*/
@customElement('vscode-textarea')
export class VscodeTextarea
@@ -98,6 +100,12 @@ export class VscodeTextarea
@property()
resize: 'both' | 'horizontal' | 'vertical' | 'none' = 'none';
+ /**
+ * The size of the textarea. The `medium` size is the default.
+ */
+ @property({reflect: true})
+ size: FormControlSize = 'medium';
+
@property({type: Boolean, reflect: true})
required = false;
diff --git a/src/vscode-textfield/vscode-textfield.styles.ts b/src/vscode-textfield/vscode-textfield.styles.ts
index 69967e364..d430728e8 100644
--- a/src/vscode-textfield/vscode-textfield.styles.ts
+++ b/src/vscode-textfield/vscode-textfield.styles.ts
@@ -68,7 +68,10 @@ const styles: CSSResultGroup = [
color: var(--vscode-settings-textInputForeground, #cccccc);
display: block;
font-family: var(--vscode-font-family, ${defaultFontStack});
- font-size: var(--vscode-font-size, 13px);
+ font-size: var(
+ --vsc-form-control-font-size,
+ var(--vscode-font-size, 13px)
+ );
font-weight: var(--vscode-font-weight, normal);
line-height: 18px;
outline: none;
@@ -79,6 +82,24 @@ const styles: CSSResultGroup = [
width: 100%;
}
+ :host([size='small']) {
+ --vsc-form-control-font-size: 12px;
+ }
+
+ :host([size='large']) {
+ --vsc-form-control-font-size: 15px;
+ }
+
+ :host([size='small']) input {
+ padding-bottom: 2px;
+ padding-top: 2px;
+ }
+
+ :host([size='large']) input {
+ padding-bottom: 5px;
+ padding-top: 5px;
+ }
+
input:read-only:not([type='file']) {
cursor: not-allowed;
}
diff --git a/src/vscode-textfield/vscode-textfield.test.ts b/src/vscode-textfield/vscode-textfield.test.ts
index 8968af222..0046e03eb 100644
--- a/src/vscode-textfield/vscode-textfield.test.ts
+++ b/src/vscode-textfield/vscode-textfield.test.ts
@@ -50,6 +50,25 @@ describe('vscode-textfield', () => {
expect(el.type).to.eq('text');
});
+ it('uses medium size by default', async () => {
+ const el = await fixture(
+ html``
+ );
+
+ expect(el.size).to.eq('medium');
+ expect(el.getAttribute('size')).to.eq('medium');
+ });
+
+ it('reflects the size property', async () => {
+ const el = await fixture(
+ html``
+ );
+ el.size = 'small';
+ await el.updateComplete;
+
+ expect(el.getAttribute('size')).to.eq('small');
+ });
+
it('should be participated in the form', async () => {
const form = document.createElement('form');
await fixture(
diff --git a/src/vscode-textfield/vscode-textfield.ts b/src/vscode-textfield/vscode-textfield.ts
index 3af6cf18e..b472ee444 100644
--- a/src/vscode-textfield/vscode-textfield.ts
+++ b/src/vscode-textfield/vscode-textfield.ts
@@ -2,6 +2,7 @@ import {html, LitElement, TemplateResult} from 'lit';
import {property, query, state} from 'lit/decorators.js';
import {ifDefined} from 'lit/directives/if-defined.js';
import {customElement, VscElement} from '../includes/VscElement.js';
+import {FormControlSize} from '../includes/form-control-size.js';
import styles from './vscode-textfield.styles.js';
import {AssociatedFormControl} from '../includes/AssociatedFormControl.js';
@@ -48,6 +49,7 @@ type InputType =
* @cssprop [--vscode-button-background=#0078d4]
* @cssprop [--vscode-button-foreground=#ffffff]
* @cssprop [--vscode-button-hoverBackground=#026ec1]
+ * @cssprop [--vsc-form-control-font-size=var(--vscode-font-size, 13px)] - Font size of the input. It is set automatically by the `size` property.
*/
@customElement('vscode-textfield')
export class VscodeTextfield
@@ -129,6 +131,12 @@ export class VscodeTextfield
@property({type: Boolean, reflect: true})
required = false;
+ /**
+ * The size of the textfield. The `medium` size is the default.
+ */
+ @property({reflect: true})
+ size: FormControlSize = 'medium';
+
@property({type: Number})
step: number | undefined = undefined;
From 5f8ced3c1feb7788739d34ff047261c1c33bc699 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 29 Aug 2026 02:43:56 +0000
Subject: [PATCH 04/31] style: simplify padding shorthand in select large size
rule
Co-authored-by: 171h <40647432+171h@users.noreply.github.com>
---
src/includes/vscode-select/styles.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/includes/vscode-select/styles.ts b/src/includes/vscode-select/styles.ts
index cabe3ed75..b1db70d21 100644
--- a/src/includes/vscode-select/styles.ts
+++ b/src/includes/vscode-select/styles.ts
@@ -25,7 +25,7 @@ export default [
}
:host([size='large']) .select-face {
- padding: 4px 4px;
+ padding: 4px;
}
:host([size='small']) .combobox-input {
From eb960ef6f9399d46dd9fc741fb3fdd6dac3105fe Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 29 Aug 2026 02:55:38 +0000
Subject: [PATCH 05/31] dev: add interactive size switcher demos for form
components
Co-authored-by: 171h <40647432+171h@users.noreply.github.com>
---
dev/vscode-button/size.html | 45 ++++++++++++
dev/vscode-checkbox/size.html | 49 +++++++++++++
dev/vscode-form-group/size.html | 110 +++++++++++++++++++++++++++++
dev/vscode-multi-select/size.html | 49 +++++++++++++
dev/vscode-radio/size.html | 52 ++++++++++++++
dev/vscode-single-select/size.html | 49 +++++++++++++
dev/vscode-textarea/size.html | 49 +++++++++++++
dev/vscode-textfield/size.html | 49 +++++++++++++
8 files changed, 452 insertions(+)
create mode 100644 dev/vscode-button/size.html
create mode 100644 dev/vscode-checkbox/size.html
create mode 100644 dev/vscode-form-group/size.html
create mode 100644 dev/vscode-multi-select/size.html
create mode 100644 dev/vscode-radio/size.html
create mode 100644 dev/vscode-single-select/size.html
create mode 100644 dev/vscode-textarea/size.html
create mode 100644 dev/vscode-textfield/size.html
diff --git a/dev/vscode-button/size.html b/dev/vscode-button/size.html
new file mode 100644
index 000000000..2015781ad
--- /dev/null
+++ b/dev/vscode-button/size.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+ VSCode Elements
+
+
+
+
+
+
+
+ Button sizes
+
+
+ Button
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/vscode-checkbox/size.html b/dev/vscode-checkbox/size.html
new file mode 100644
index 000000000..1491be1a4
--- /dev/null
+++ b/dev/vscode-checkbox/size.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+ VSCode Elements
+
+
+
+
+
+
+
+ Checkbox sizes
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/vscode-form-group/size.html b/dev/vscode-form-group/size.html
new file mode 100644
index 000000000..2e56e0f22
--- /dev/null
+++ b/dev/vscode-form-group/size.html
@@ -0,0 +1,110 @@
+
+
+
+
+
+ VSCode Elements
+
+
+
+
+
+
+
+ Form group sizes
+
+ The size of the form group is propagated to the slotted form controls.
+
+
+
+
+
+ Textfield
+
+ Helper text
+
+
+ Textarea
+
+
+
+ Single select
+
+ Lorem
+ Ipsum
+ Dolor
+
+
+
+ Multi select
+
+ Lorem
+ Ipsum
+ Dolor
+
+
+
+ Checkbox
+
+
+
+
+
+
+ Radio
+
+ Lorem
+ Ipsum
+
+
+
+ Save
+ Cancel
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/vscode-multi-select/size.html b/dev/vscode-multi-select/size.html
new file mode 100644
index 000000000..378757e0e
--- /dev/null
+++ b/dev/vscode-multi-select/size.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+ VSCode Elements
+
+
+
+
+
+
+
+ Multi select sizes
+
+
+
+ Lorem
+ Ipsum
+ Dolor
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/vscode-radio/size.html b/dev/vscode-radio/size.html
new file mode 100644
index 000000000..4fc054011
--- /dev/null
+++ b/dev/vscode-radio/size.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+ VSCode Elements
+
+
+
+
+
+
+
+ Radio sizes
+
+
+
+ Lorem
+ Ipsum
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/vscode-single-select/size.html b/dev/vscode-single-select/size.html
new file mode 100644
index 000000000..fef4efe7a
--- /dev/null
+++ b/dev/vscode-single-select/size.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+ VSCode Elements
+
+
+
+
+
+
+
+ Single select sizes
+
+
+
+ Lorem
+ Ipsum
+ Dolor
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/vscode-textarea/size.html b/dev/vscode-textarea/size.html
new file mode 100644
index 000000000..889789460
--- /dev/null
+++ b/dev/vscode-textarea/size.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+ VSCode Elements
+
+
+
+
+
+
+
+ Textarea sizes
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/vscode-textfield/size.html b/dev/vscode-textfield/size.html
new file mode 100644
index 000000000..39fbe93d9
--- /dev/null
+++ b/dev/vscode-textfield/size.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+ VSCode Elements
+
+
+
+
+
+
+
+ Textfield sizes
+
+
+
+
+
+
+
+
+
+
+
+
+
From cebd8f8b5e65bf00dea9dec287bd65b3b0aea25d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 29 Aug 2026 02:57:03 +0000
Subject: [PATCH 06/31] dev: address review feedback on size demos
Co-authored-by: 171h <40647432+171h@users.noreply.github.com>
---
dev/vscode-form-group/size.html | 4 +++-
dev/vscode-radio/size.html | 8 +++++---
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/dev/vscode-form-group/size.html b/dev/vscode-form-group/size.html
index 2e56e0f22..4313de30d 100644
--- a/dev/vscode-form-group/size.html
+++ b/dev/vscode-form-group/size.html
@@ -20,7 +20,9 @@
Form group sizes
- The size of the form group is propagated to the slotted form controls.
+ The font size of the slotted form controls follows the form group size
+ automatically. Size-specific spacing adjustments are applied when the
+ size attribute is also set on the slotted controls.
diff --git a/dev/vscode-radio/size.html b/dev/vscode-radio/size.html
index 4fc054011..be107a756 100644
--- a/dev/vscode-radio/size.html
+++ b/dev/vscode-radio/size.html
@@ -21,11 +21,13 @@
Radio sizes
-
-
+ Lorem
- Ipsum
+ Ipsum
From 13f6ee857f977a8483597f4a16e3fbfa7d8faeb4 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 29 Aug 2026 04:53:32 +0000
Subject: [PATCH 07/31] feat: make small form controls 16px high
Co-authored-by: 171h <40647432+171h@users.noreply.github.com>
---
.../form-button-widget/base.styles.ts | 17 +++++++++---
src/includes/vscode-select/styles.ts | 27 ++++++++++++++++---
src/vscode-button/vscode-button.styles.ts | 4 +--
.../vscode-form-group.styles.ts | 2 +-
.../vscode-textfield.styles.ts | 7 ++---
5 files changed, 44 insertions(+), 13 deletions(-)
diff --git a/src/includes/form-button-widget/base.styles.ts b/src/includes/form-button-widget/base.styles.ts
index 29e4c903d..58461149c 100644
--- a/src/includes/form-button-widget/base.styles.ts
+++ b/src/includes/form-button-widget/base.styles.ts
@@ -33,16 +33,21 @@ export default [
}
:host([size='small']) {
- --vsc-form-control-font-size: 12px;
+ --vsc-form-control-font-size: 11px;
}
:host([size='large']) {
--vsc-form-control-font-size: 15px;
}
+ :host([size='small']) .wrapper {
+ line-height: 14px;
+ min-height: 16px;
+ }
+
:host([size='small']) .icon {
- height: 16px;
- width: 16px;
+ height: 14px;
+ width: 14px;
}
:host([size='large']) .icon {
@@ -50,8 +55,12 @@ export default [
width: 20px;
}
+ :host([size='small']) .label {
+ min-height: 16px;
+ }
+
:host([size='small']) .label-inner {
- padding-left: 25px;
+ padding-left: 23px;
}
:host([size='large']) .label-inner {
diff --git a/src/includes/vscode-select/styles.ts b/src/includes/vscode-select/styles.ts
index b1db70d21..b209d34e4 100644
--- a/src/includes/vscode-select/styles.ts
+++ b/src/includes/vscode-select/styles.ts
@@ -13,7 +13,7 @@ export default [
}
:host([size='small']) {
- --vsc-form-control-font-size: 12px;
+ --vsc-form-control-font-size: 11px;
}
:host([size='large']) {
@@ -21,21 +21,42 @@ export default [
}
:host([size='small']) .select-face {
- padding: 2px 4px;
+ line-height: 12px;
+ padding: 1px 4px;
}
:host([size='large']) .select-face {
padding: 4px;
}
+ :host([size='small']) .select-face .text {
+ height: 12px;
+ }
+
+ :host([size='small']) .select-face.multiselect {
+ align-items: center;
+ display: flex;
+ }
+
+ :host([size='small']) .select-face-badge {
+ line-height: 12px;
+ margin: 0 1px;
+ padding: 0 2px;
+ }
+
:host([size='small']) .combobox-input {
- padding: 3px 4px;
+ line-height: 12px;
+ padding: 1px 4px;
}
:host([size='large']) .combobox-input {
padding: 5px 4px;
}
+ :host([size='small']) .select-face .icon {
+ top: 4px;
+ }
+
.main-slot {
display: none;
}
diff --git a/src/vscode-button/vscode-button.styles.ts b/src/vscode-button/vscode-button.styles.ts
index c0a9a0974..008f09f26 100644
--- a/src/vscode-button/vscode-button.styles.ts
+++ b/src/vscode-button/vscode-button.styles.ts
@@ -53,7 +53,7 @@ const styles: CSSResultGroup = [
}
:host([size='small']) {
- --vsc-form-control-font-size: 12px;
+ --vsc-form-control-font-size: 11px;
}
:host([size='large']) {
@@ -61,7 +61,7 @@ const styles: CSSResultGroup = [
}
:host([size='small']) .base {
- line-height: 18px;
+ line-height: 12px;
padding: 1px calc(9px + var(--vsc-base-additional-right-padding, 0px)) 1px
9px;
}
diff --git a/src/vscode-form-group/vscode-form-group.styles.ts b/src/vscode-form-group/vscode-form-group.styles.ts
index 741aa658d..903619a9b 100644
--- a/src/vscode-form-group/vscode-form-group.styles.ts
+++ b/src/vscode-form-group/vscode-form-group.styles.ts
@@ -14,7 +14,7 @@ const styles: CSSResultGroup = [
:host([size='small']) {
--label-right-margin: 10px;
--label-width: 100px;
- --vsc-form-control-font-size: 12px;
+ --vsc-form-control-font-size: 11px;
margin: 8px 0;
}
diff --git a/src/vscode-textfield/vscode-textfield.styles.ts b/src/vscode-textfield/vscode-textfield.styles.ts
index d430728e8..93bd531e3 100644
--- a/src/vscode-textfield/vscode-textfield.styles.ts
+++ b/src/vscode-textfield/vscode-textfield.styles.ts
@@ -83,7 +83,7 @@ const styles: CSSResultGroup = [
}
:host([size='small']) {
- --vsc-form-control-font-size: 12px;
+ --vsc-form-control-font-size: 11px;
}
:host([size='large']) {
@@ -91,8 +91,9 @@ const styles: CSSResultGroup = [
}
:host([size='small']) input {
- padding-bottom: 2px;
- padding-top: 2px;
+ line-height: 12px;
+ padding-bottom: 1px;
+ padding-top: 1px;
}
:host([size='large']) input {
From 1ace17078441c4335c45ed10e24cfbf0948bb0e0 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 29 Aug 2026 04:55:12 +0000
Subject: [PATCH 08/31] fix: center dropdown icon in small select face
Co-authored-by: 171h <40647432+171h@users.noreply.github.com>
---
src/includes/vscode-select/styles.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/includes/vscode-select/styles.ts b/src/includes/vscode-select/styles.ts
index b209d34e4..05b4b9e70 100644
--- a/src/includes/vscode-select/styles.ts
+++ b/src/includes/vscode-select/styles.ts
@@ -54,7 +54,7 @@ export default [
}
:host([size='small']) .select-face .icon {
- top: 4px;
+ top: 0;
}
.main-slot {
From c9bd8036b0791da4ed4f2d784d2ee37a0beef7f4 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 29 Aug 2026 05:05:20 +0000
Subject: [PATCH 09/31] dev: replace size.html pages with size switcher buttons
in existing demos
Co-authored-by: 171h <40647432+171h@users.noreply.github.com>
---
dev/vscode-button/basic-examples.html | 20 ++++
dev/vscode-button/size.html | 45 -------
dev/vscode-checkbox/basic-example.html | 19 +++
dev/vscode-checkbox/size.html | 49 --------
dev/vscode-form-group/size.html | 112 ------------------
dev/vscode-label/basic-example.html | 23 ++++
dev/vscode-multi-select/combobox.html | 17 +++
dev/vscode-multi-select/size.html | 49 --------
dev/vscode-radio-group/checked.html | 19 +++
dev/vscode-radio/size.html | 54 ---------
.../select-mode/basic-example.html | 17 +++
dev/vscode-single-select/size.html | 49 --------
dev/vscode-textarea/csp.html | 26 +++-
dev/vscode-textarea/size.html | 49 --------
dev/vscode-textfield/basic-example.html | 17 +++
dev/vscode-textfield/size.html | 49 --------
16 files changed, 157 insertions(+), 457 deletions(-)
delete mode 100644 dev/vscode-button/size.html
delete mode 100644 dev/vscode-checkbox/size.html
delete mode 100644 dev/vscode-form-group/size.html
delete mode 100644 dev/vscode-multi-select/size.html
delete mode 100644 dev/vscode-radio/size.html
delete mode 100644 dev/vscode-single-select/size.html
delete mode 100644 dev/vscode-textarea/size.html
delete mode 100644 dev/vscode-textfield/size.html
diff --git a/dev/vscode-button/basic-examples.html b/dev/vscode-button/basic-examples.html
index 6bdd50a49..211a40dda 100644
--- a/dev/vscode-button/basic-examples.html
+++ b/dev/vscode-button/basic-examples.html
@@ -28,6 +28,26 @@
Primary Button
Secondary Button
+
+
+
+
+
+
-
- Button sizes
-
-
- Button
-
-
-
-
-
-
-
-
-
diff --git a/dev/vscode-button/size.html b/dev/vscode-button/size.html
deleted file mode 100644
index 2015781ad..000000000
--- a/dev/vscode-button/size.html
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-