From d38dea52fa4aea09c4f19732574ffa2107b5bb11 Mon Sep 17 00:00:00 2001 From: bendera Date: Sat, 21 Jun 2025 16:15:18 +0200 Subject: [PATCH 01/33] FIx sync issues --- src/vscode-scrollable/vscode-scrollable.ts | 64 +++++++++++----------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index b547cc4fb..ca5076007 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -26,16 +26,14 @@ export class VscodeScrollable extends VscElement { @property({type: Number, attribute: 'scroll-pos'}) set scrollPos(val: number) { - this._scrollableContainer.scrollTop = val; + this._scrollPos = val; } get scrollPos(): number { - if (!this._scrollableContainer) { - return 0; - } - - return this._scrollableContainer.scrollTop; + return this._scrollPos; } + private _scrollPos = 0; + @property({type: Number, attribute: 'scroll-max'}) get scrollMax(): number { if (!this._scrollableContainer) { @@ -82,6 +80,12 @@ export class VscodeScrollable extends VscElement { private _scrollbarVisible = true; private _scrollbarTrackZ = 0; + constructor() { + super(); + this.addEventListener('mouseover', this._handleComponentMouseOver); + this.addEventListener('mouseout', this._handleComponentMouseOut); + } + override connectedCallback(): void { super.connectedCallback(); @@ -100,9 +104,6 @@ export class VscodeScrollable extends VscElement { this._hostResizeObserver.observe(this); this._contentResizeObserver.observe(this._contentElement); }); - - this.addEventListener('mouseover', this._onComponentMouseOverBound); - this.addEventListener('mouseout', this._onComponentMouseOutBound); } override disconnectedCallback(): void { @@ -112,9 +113,6 @@ export class VscodeScrollable extends VscElement { this._hostResizeObserver.disconnect(); this._contentResizeObserver.unobserve(this._contentElement); this._contentResizeObserver.disconnect(); - - this.removeEventListener('mouseover', this._onComponentMouseOverBound); - this.removeEventListener('mouseout', this._onComponentMouseOutBound); } private _resizeObserverCallback = () => { @@ -156,7 +154,22 @@ export class VscodeScrollable extends VscElement { this.requestUpdate(); } + private _updateThumb() { + const scrollTop = this._scrollableContainer.scrollTop; + this.scrolled = scrollTop > 0; + + const cmpH = this.getBoundingClientRect().height; + const thumbH = this._scrollThumbElement.getBoundingClientRect().height; + const contentH = this._contentElement.getBoundingClientRect().height; + + const overflown = contentH - cmpH; + const ratio = scrollTop / overflown; + + this._thumbY = ratio * (cmpH - thumbH); + } + private _onSlotChange = () => { + this._updateThumb(); this._zIndexFix(); }; @@ -220,34 +233,22 @@ export class VscodeScrollable extends VscElement { private _onScrollThumbMouseUpBound = this._onScrollThumbMouseUp.bind(this); private _onScrollableContainerScroll() { - const scrollTop = this._scrollableContainer.scrollTop; - this.scrolled = scrollTop > 0; - - const cmpH = this.getBoundingClientRect().height; - const thumbH = this._scrollThumbElement.getBoundingClientRect().height; - const contentH = this._contentElement.getBoundingClientRect().height; - - const overflown = contentH - cmpH; - const ratio = scrollTop / overflown; - - this._thumbY = ratio * (cmpH - thumbH); + this._updateThumb(); } - private _onComponentMouseOver() { + private _handleComponentMouseOver = () => { + this._updateThumb(); + this._thumbVisible = true; this._thumbFade = false; - } - - private _onComponentMouseOverBound = this._onComponentMouseOver.bind(this); + }; - private _onComponentMouseOut() { + private _handleComponentMouseOut = () => { if (!this._thumbActive) { this._thumbVisible = false; this._thumbFade = true; } - } - - private _onComponentMouseOutBound = this._onComponentMouseOut.bind(this); + }; override render(): TemplateResult { return html` @@ -256,6 +257,7 @@ export class VscodeScrollable extends VscElement { .style=${stylePropertyMap({ userSelect: this._isDragging ? 'none' : 'auto', })} + .scrollTop=${this._scrollPos} >
Date: Sat, 21 Jun 2025 16:16:14 +0200 Subject: [PATCH 02/33] Use scrollable component --- src/includes/vscode-select/styles.ts | 9 +++++++-- .../vscode-select/vscode-select-base.ts | 19 ++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/includes/vscode-select/styles.ts b/src/includes/vscode-select/styles.ts index 742c08a20..24255338a 100644 --- a/src/includes/vscode-select/styles.ts +++ b/src/includes/vscode-select/styles.ts @@ -189,13 +189,18 @@ export default [ border-color: var(--vscode-focusBorder, #0078d4); } + .scrollable { + display: block; + max-height: 222px; + margin: 0; + overflow: hidden; + } + .options { box-sizing: border-box; cursor: pointer; list-style: none; margin: 0; - max-height: 222px; - overflow: auto; padding: 1px; } diff --git a/src/includes/vscode-select/vscode-select-base.ts b/src/includes/vscode-select/vscode-select-base.ts index bfb89eff0..b7392089d 100644 --- a/src/includes/vscode-select/vscode-select-base.ts +++ b/src/includes/vscode-select/vscode-select-base.ts @@ -12,11 +12,13 @@ import {when} from 'lit/directives/when.js'; import '../../vscode-button/index.js'; 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 {filterOptionsByPattern, highlightRanges} from './helpers.js'; import type {InternalOption, Option, FilterMethod} from './types.js'; import {OptionListController} from './OptionListController.js'; import {checkIcon} from './template-elements.js'; +import '../../vscode-scrollable/vscode-scrollable.js'; export const VISIBLE_OPTS = 10; export const OPT_HEIGHT = 22; @@ -634,8 +636,6 @@ export class VscodeSelectBase extends VscElement { tabindex="-1" @click=${this._onOptionClick} @mouseover=${this._onOptionMouseOver} - @scroll=${this._onOptionListScroll} - .scrollTop=${this._optionListScrollPos} > ${repeat( list, @@ -748,10 +748,23 @@ export class VscodeSelectBase extends VscElement { open: this.open, }; + const scrollPaneHeight = Math.min( + this._opts.numOfVisibleOptions * OPT_HEIGHT + 2, + VISIBLE_OPTS * OPT_HEIGHT + 2 + ); + return html`
${this.position === 'above' ? this._renderDescription() : nothing} - ${this._renderOptions()} ${this._renderDropdownControls()} + + ${this._renderOptions()} ${this._renderDropdownControls()} + ${this.position === 'below' ? this._renderDescription() : nothing}
`; From 5054df382388e6d5d0f51ea30586f461ca35f57a Mon Sep 17 00:00:00 2001 From: bendera Date: Sat, 21 Jun 2025 16:16:44 +0200 Subject: [PATCH 03/33] Add alwaysVisible property --- dev/vscode-scrollable/always-visible.html | 66 ++++++++++++++++++++++ src/vscode-scrollable/vscode-scrollable.ts | 7 ++- 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 dev/vscode-scrollable/always-visible.html diff --git a/dev/vscode-scrollable/always-visible.html b/dev/vscode-scrollable/always-visible.html new file mode 100644 index 000000000..6e3b8abd4 --- /dev/null +++ b/dev/vscode-scrollable/always-visible.html @@ -0,0 +1,66 @@ + + + + + + + VSCode Elements + + + + + + + + + +

Apply CSP

+
+ + +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam + volutpat ex sit amet venenatis auctor. Nunc semper consequat diam + sit amet eleifend. Ut a viverra nulla. Fusce vel sapien quis metus + vestibulum dignissim in sit amet orci. Sed lorem diam, scelerisque + non urna ac, egestas suscipit eros. Donec consequat tristique + lectus, quis placerat metus venenatis a. Nam fringilla lectus + finibus iaculis dictum. Maecenas in risus velit. Vestibulum ante + ipsum primis in faucibus orci luctus et ultrices posuere cubilia + curae; +

+
aaa
+
+
+
+ + diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index ca5076007..be0ba05a2 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -18,6 +18,9 @@ import styles from './vscode-scrollable.styles.js'; export class VscodeScrollable extends VscElement { static override styles = styles; + @property({type: Boolean, reflect: true, attribute: 'always-visible'}) + alwaysVisible = false; + @property({type: Boolean, reflect: true}) shadow = true; @@ -277,8 +280,8 @@ export class VscodeScrollable extends VscElement {
Date: Sat, 21 Jun 2025 16:23:18 +0200 Subject: [PATCH 04/33] Does not allow focusing scrollable --- src/includes/vscode-select/vscode-select-base.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/includes/vscode-select/vscode-select-base.ts b/src/includes/vscode-select/vscode-select-base.ts index b7392089d..c822c564e 100644 --- a/src/includes/vscode-select/vscode-select-base.ts +++ b/src/includes/vscode-select/vscode-select-base.ts @@ -759,6 +759,7 @@ export class VscodeSelectBase extends VscElement { Date: Sat, 21 Jun 2025 16:28:24 +0200 Subject: [PATCH 05/33] Refactor --- src/vscode-scrollable/vscode-scrollable.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index be0ba05a2..4c015b351 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -123,14 +123,14 @@ export class VscodeScrollable extends VscElement { }; private _updateScrollbar() { - const compCr = this.getBoundingClientRect(); - const contentCr = this._contentElement.getBoundingClientRect(); + const contentHeight = this._contentElement.offsetHeight; + const componentHeight = this.offsetHeight; - if (compCr.height >= contentCr.height) { + if (componentHeight >= contentHeight) { this._scrollbarVisible = false; } else { this._scrollbarVisible = true; - this._thumbHeight = compCr.height * (compCr.height / contentCr.height); + this._thumbHeight = componentHeight * (componentHeight / contentHeight); } this.requestUpdate(); From 64d294a0fbc027675d9b339d25cf21355c86fe80 Mon Sep 17 00:00:00 2001 From: bendera Date: Sat, 21 Jun 2025 22:36:52 +0200 Subject: [PATCH 06/33] Refactor scroll handler --- src/vscode-scrollable/vscode-scrollable.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index 4c015b351..7db2a61c6 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -102,7 +102,7 @@ export class VscodeScrollable extends VscElement { this.updateComplete.then(() => { this._scrollableContainer.addEventListener( 'scroll', - this._onScrollableContainerScroll.bind(this) + this._handleScrollableContainerScroll ); this._hostResizeObserver.observe(this); this._contentResizeObserver.observe(this._contentElement); @@ -235,9 +235,9 @@ export class VscodeScrollable extends VscElement { private _onScrollThumbMouseUpBound = this._onScrollThumbMouseUp.bind(this); - private _onScrollableContainerScroll() { + private _handleScrollableContainerScroll = () => { this._updateThumb(); - } + }; private _handleComponentMouseOver = () => { this._updateThumb(); From c220f0c52d1c86b5ce22bcfaba61c30f22abb233 Mon Sep 17 00:00:00 2001 From: bendera Date: Sat, 21 Jun 2025 22:51:50 +0200 Subject: [PATCH 07/33] Refactor --- src/vscode-scrollable/vscode-scrollable.ts | 40 +++++++++------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index 7db2a61c6..fa753a7fe 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -161,22 +161,22 @@ export class VscodeScrollable extends VscElement { const scrollTop = this._scrollableContainer.scrollTop; this.scrolled = scrollTop > 0; - const cmpH = this.getBoundingClientRect().height; - const thumbH = this._scrollThumbElement.getBoundingClientRect().height; - const contentH = this._contentElement.getBoundingClientRect().height; + const componentH = this.offsetHeight; + const thumbH = this._scrollThumbElement.offsetHeight; + const contentH = this._contentElement.offsetHeight; - const overflown = contentH - cmpH; + const overflown = contentH - componentH; const ratio = scrollTop / overflown; - this._thumbY = ratio * (cmpH - thumbH); + this._thumbY = ratio * (componentH - thumbH); } - private _onSlotChange = () => { + private _handleSlotChange = () => { this._updateThumb(); this._zIndexFix(); }; - private _onScrollThumbMouseDown(event: MouseEvent) { + private _handleScrollThumbMouseDown(event: MouseEvent) { const cmpCr = this.getBoundingClientRect(); const thCr = this._scrollThumbElement.getBoundingClientRect(); @@ -185,11 +185,11 @@ export class VscodeScrollable extends VscElement { this._isDragging = true; this._thumbActive = true; - document.addEventListener('mousemove', this._onScrollThumbMouseMoveBound); - document.addEventListener('mouseup', this._onScrollThumbMouseUpBound); + document.addEventListener('mousemove', this._handleScrollThumbMouseMove); + document.addEventListener('mouseup', this._handleScrollThumbMouseUp); } - private _onScrollThumbMouseMove(event: MouseEvent) { + private _handleScrollThumbMouseMove = (event: MouseEvent) => { const predictedPos = this._scrollThumbStartY + (event.screenY - this._mouseStartY); let nextPos = 0; @@ -208,12 +208,9 @@ export class VscodeScrollable extends VscElement { this._thumbY = nextPos; this._scrollableContainer.scrollTop = (nextPos / (cmpH - thumbH)) * (contentH - cmpH); - } - - private _onScrollThumbMouseMoveBound = - this._onScrollThumbMouseMove.bind(this); + }; - private _onScrollThumbMouseUp(event: MouseEvent) { + private _handleScrollThumbMouseUp = (event: MouseEvent) => { this._isDragging = false; this._thumbActive = false; @@ -226,15 +223,10 @@ export class VscodeScrollable extends VscElement { this._thumbVisible = false; } - document.removeEventListener( - 'mousemove', - this._onScrollThumbMouseMoveBound - ); - document.removeEventListener('mouseup', this._onScrollThumbMouseUpBound); + document.removeEventListener('mousemove', this._handleScrollThumbMouseMove); + document.removeEventListener('mouseup', this._handleScrollThumbMouseUp); } - private _onScrollThumbMouseUpBound = this._onScrollThumbMouseUp.bind(this); - private _handleScrollableContainerScroll = () => { this._updateThumb(); }; @@ -288,11 +280,11 @@ export class VscodeScrollable extends VscElement { height: `${this._thumbHeight}px`, top: `${this._thumbY}px`, })} - @mousedown=${this._onScrollThumbMouseDown} + @mousedown=${this._handleScrollThumbMouseDown} >
- +
`; From 1fc80cf1ad4bff4690c18d4e9197d8409dd839b0 Mon Sep 17 00:00:00 2001 From: bendera Date: Sat, 21 Jun 2025 23:07:23 +0200 Subject: [PATCH 08/33] Refactor --- src/vscode-scrollable/vscode-scrollable.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index fa753a7fe..76ca674a0 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -206,8 +206,7 @@ export class VscodeScrollable extends VscElement { } this._thumbY = nextPos; - this._scrollableContainer.scrollTop = - (nextPos / (cmpH - thumbH)) * (contentH - cmpH); + this._scrollPos = (nextPos / (cmpH - thumbH)) * (contentH - cmpH); }; private _handleScrollThumbMouseUp = (event: MouseEvent) => { @@ -225,7 +224,7 @@ export class VscodeScrollable extends VscElement { document.removeEventListener('mousemove', this._handleScrollThumbMouseMove); document.removeEventListener('mouseup', this._handleScrollThumbMouseUp); - } + }; private _handleScrollableContainerScroll = () => { this._updateThumb(); From 9a69e6b100017f797dd2503f35f903208850327b Mon Sep 17 00:00:00 2001 From: bendera Date: Sat, 21 Jun 2025 23:19:22 +0200 Subject: [PATCH 09/33] Renaming --- src/vscode-scrollable/vscode-scrollable.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index 76ca674a0..a5370b341 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -157,7 +157,7 @@ export class VscodeScrollable extends VscElement { this.requestUpdate(); } - private _updateThumb() { + private _updateThumbPosition() { const scrollTop = this._scrollableContainer.scrollTop; this.scrolled = scrollTop > 0; @@ -171,8 +171,9 @@ export class VscodeScrollable extends VscElement { this._thumbY = ratio * (componentH - thumbH); } + //#region event handlers private _handleSlotChange = () => { - this._updateThumb(); + this._updateThumbPosition(); this._zIndexFix(); }; @@ -227,11 +228,11 @@ export class VscodeScrollable extends VscElement { }; private _handleScrollableContainerScroll = () => { - this._updateThumb(); + this._updateThumbPosition(); }; private _handleComponentMouseOver = () => { - this._updateThumb(); + this._updateThumbPosition(); this._thumbVisible = true; this._thumbFade = false; @@ -244,6 +245,8 @@ export class VscodeScrollable extends VscElement { } }; + //#endregion + override render(): TemplateResult { return html`
Date: Sun, 22 Jun 2025 13:53:45 +0200 Subject: [PATCH 10/33] Fix thumb position sync issues in Scrollable --- dev/vscode-scrollable/change-event.html | 85 ++++++++++++++++++++++ src/vscode-scrollable/vscode-scrollable.ts | 32 ++++++-- 2 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 dev/vscode-scrollable/change-event.html diff --git a/dev/vscode-scrollable/change-event.html b/dev/vscode-scrollable/change-event.html new file mode 100644 index 000000000..a20a03897 --- /dev/null +++ b/dev/vscode-scrollable/change-event.html @@ -0,0 +1,85 @@ + + + + + + VSCode Elements + + + + + + + + + +
+ + +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam + volutpat ex sit amet venenatis auctor. Nunc semper consequat diam + sit amet eleifend. Ut a viverra nulla. Fusce vel sapien quis metus + vestibulum dignissim in sit amet orci. Sed lorem diam, scelerisque + non urna ac, egestas suscipit eros. Donec consequat tristique + lectus, quis placerat metus venenatis a. Nam fringilla lectus + finibus iaculis dictum. Maecenas in risus velit. Vestibulum ante + ipsum primis in faucibus orci luctus et ultrices posuere cubilia + curae; +

+

 

+

 

+

 

+

 

+
aaa
+
+
+
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam volutpat + ex sit amet venenatis auctor. Nunc semper consequat diam sit amet + eleifend. Ut a viverra nulla. Fusce vel sapien quis metus vestibulum + dignissim in sit amet orci. Sed lorem diam, scelerisque non urna ac, + egestas suscipit eros. Donec consequat tristique lectus, quis placerat + metus venenatis a. Nam fringilla lectus finibus iaculis dictum. + Maecenas in risus velit. Vestibulum ante ipsum primis in faucibus orci + luctus et ultrices posuere cubilia curae; +

+

 

+

 

+

 

+

 

+
aaa
+
+
+ + + diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index a5370b341..353186870 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -1,4 +1,4 @@ -import {html, nothing, TemplateResult} from 'lit'; +import {html, nothing, PropertyValues, TemplateResult} from 'lit'; import {property, query, queryAssignedElements, state} from 'lit/decorators.js'; import {classMap} from 'lit/directives/class-map.js'; import {customElement, VscElement} from '../includes/VscElement.js'; @@ -30,6 +30,8 @@ export class VscodeScrollable extends VscElement { @property({type: Number, attribute: 'scroll-pos'}) set scrollPos(val: number) { this._scrollPos = val; + this._updateThumbPosition(); + this.requestUpdate(); } get scrollPos(): number { return this._scrollPos; @@ -106,6 +108,7 @@ export class VscodeScrollable extends VscElement { ); this._hostResizeObserver.observe(this); this._contentResizeObserver.observe(this._contentElement); + this._updateThumbPosition(); }); } @@ -118,6 +121,10 @@ export class VscodeScrollable extends VscElement { this._contentResizeObserver.disconnect(); } + protected override firstUpdated(_changedProperties: PropertyValues): void { + this._updateThumbPosition(); + } + private _resizeObserverCallback = () => { this._updateScrollbar(); }; @@ -158,17 +165,22 @@ export class VscodeScrollable extends VscElement { } private _updateThumbPosition() { - const scrollTop = this._scrollableContainer.scrollTop; + if (!this._scrollableContainer) { + return; + } + + const scrollTop = this._scrollPos; this.scrolled = scrollTop > 0; const componentH = this.offsetHeight; - const thumbH = this._scrollThumbElement.offsetHeight; + const thumbH = this._thumbHeight; const contentH = this._contentElement.offsetHeight; const overflown = contentH - componentH; const ratio = scrollTop / overflown; + const thumbYMax = componentH - thumbH; - this._thumbY = ratio * (componentH - thumbH); + this._thumbY = Math.min(ratio * (componentH - thumbH), thumbYMax); } //#region event handlers @@ -232,8 +244,6 @@ export class VscodeScrollable extends VscElement { }; private _handleComponentMouseOver = () => { - this._updateThumbPosition(); - this._thumbVisible = true; this._thumbFade = false; }; @@ -245,6 +255,15 @@ export class VscodeScrollable extends VscElement { } }; + private _handleScroll = () => { + this._scrollPos = this._scrollableContainer.scrollTop; + this.dispatchEvent( + new CustomEvent('vsc-scrollable-change', { + detail: this._scrollPos, + }) + ); + }; + //#endregion override render(): TemplateResult { @@ -255,6 +274,7 @@ export class VscodeScrollable extends VscElement { userSelect: this._isDragging ? 'none' : 'auto', })} .scrollTop=${this._scrollPos} + @scroll=${this._handleScroll} >
Date: Sun, 22 Jun 2025 13:56:31 +0200 Subject: [PATCH 11/33] Scrollable fixes in the Select dropdown --- src/includes/vscode-select/styles.ts | 4 ++-- .../vscode-select/vscode-select-base.ts | 20 +++++++------------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/includes/vscode-select/styles.ts b/src/includes/vscode-select/styles.ts index 24255338a..ffb82a50f 100644 --- a/src/includes/vscode-select/styles.ts +++ b/src/includes/vscode-select/styles.ts @@ -192,7 +192,7 @@ export default [ .scrollable { display: block; max-height: 222px; - margin: 0; + margin: 1px 0; overflow: hidden; } @@ -201,7 +201,7 @@ export default [ cursor: pointer; list-style: none; margin: 0; - padding: 1px; + padding: 0 1px; } .option { diff --git a/src/includes/vscode-select/vscode-select-base.ts b/src/includes/vscode-select/vscode-select-base.ts index c822c564e..c71f802b2 100644 --- a/src/includes/vscode-select/vscode-select-base.ts +++ b/src/includes/vscode-select/vscode-select-base.ts @@ -1,10 +1,5 @@ import {html, render, nothing, TemplateResult, PropertyValues} from 'lit'; -import { - eventOptions, - property, - queryAssignedElements, - state, -} from 'lit/decorators.js'; +import {property, queryAssignedElements, state} from 'lit/decorators.js'; import {classMap} from 'lit/directives/class-map.js'; import {ifDefined} from 'lit/directives/if-defined.js'; import {repeat} from 'lit/directives/repeat.js'; @@ -411,10 +406,9 @@ export class VscodeSelectBase extends VscElement { } } - @eventOptions({passive: true}) - protected _onOptionListScroll(ev: Event) { - this._optionListScrollPos = (ev.target as HTMLUListElement).scrollTop; - } + private _onOptionListScroll = (ev: CustomEvent) => { + this._optionListScrollPos = ev.detail; + }; protected _onOptionMouseOver(ev: MouseEvent): void { if (this._isHoverForbidden) { @@ -749,8 +743,8 @@ export class VscodeSelectBase extends VscElement { }; const scrollPaneHeight = Math.min( - this._opts.numOfVisibleOptions * OPT_HEIGHT + 2, - VISIBLE_OPTS * OPT_HEIGHT + 2 + this._opts.numOfVisibleOptions * OPT_HEIGHT, + VISIBLE_OPTS * OPT_HEIGHT ); return html` @@ -760,7 +754,7 @@ export class VscodeSelectBase extends VscElement { always-visible class="scrollable" tabindex="-1" - @scroll=${this._onOptionListScroll} + @vsc-scrollable-change=${this._onOptionListScroll} .scrollPos=${this._optionListScrollPos} .style=${stylePropertyMap({height: `${scrollPaneHeight}px`})} > From 64268c9253dc0313af805fabf73d633e6333c9dd Mon Sep 17 00:00:00 2001 From: bendera Date: Sun, 22 Jun 2025 14:22:08 +0200 Subject: [PATCH 12/33] Don't show shadow if it's not scrolled --- src/vscode-scrollable/vscode-scrollable.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index 353186870..b0a00b5ae 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -29,7 +29,7 @@ export class VscodeScrollable extends VscElement { @property({type: Number, attribute: 'scroll-pos'}) set scrollPos(val: number) { - this._scrollPos = val; + this._scrollPos = this._limitScrollPos(val); this._updateThumbPosition(); this.requestUpdate(); } @@ -129,6 +129,21 @@ export class VscodeScrollable extends VscElement { this._updateScrollbar(); }; + private _limitScrollPos(pos: number) { + const minValue = 0; + let maxValue: number; + + if (this?.offsetHeight ?? 0 >= (this._contentElement?.offsetHeight ?? 0)) { + maxValue = 0; + } else { + maxValue = Math.max(0, this.offsetHeight - this._thumbHeight); + } + + console.log(minValue, maxValue); + + return Math.max(minValue, Math.min(maxValue, pos)); + } + private _updateScrollbar() { const contentHeight = this._contentElement.offsetHeight; const componentHeight = this.offsetHeight; From 51ca9ba336a5fb0148719bcafa57d8ad6eaadf49 Mon Sep 17 00:00:00 2001 From: bendera Date: Sun, 22 Jun 2025 23:16:58 +0200 Subject: [PATCH 13/33] Scrollable improvements --- .../vscode-select/vscode-select-base.ts | 11 +++++-- src/vscode-scrollable/vscode-scrollable.ts | 29 +++++++++---------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/includes/vscode-select/vscode-select-base.ts b/src/includes/vscode-select/vscode-select-base.ts index c71f802b2..90958479e 100644 --- a/src/includes/vscode-select/vscode-select-base.ts +++ b/src/includes/vscode-select/vscode-select-base.ts @@ -742,8 +742,13 @@ export class VscodeSelectBase extends VscElement { open: this.open, }; + const visibleOptions = + this._isSuggestedOptionVisible || this._opts.numOfVisibleOptions === 0 + ? this._opts.numOfVisibleOptions + 1 + : this._opts.numOfVisibleOptions; + const scrollPaneHeight = Math.min( - this._opts.numOfVisibleOptions * OPT_HEIGHT, + visibleOptions * OPT_HEIGHT, VISIBLE_OPTS * OPT_HEIGHT ); @@ -756,7 +761,9 @@ export class VscodeSelectBase extends VscElement { tabindex="-1" @vsc-scrollable-change=${this._onOptionListScroll} .scrollPos=${this._optionListScrollPos} - .style=${stylePropertyMap({height: `${scrollPaneHeight}px`})} + .style=${stylePropertyMap({ + height: `${scrollPaneHeight}px`, + })} > ${this._renderOptions()} ${this._renderDropdownControls()} diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index b0a00b5ae..5c317ad77 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -21,6 +21,9 @@ export class VscodeScrollable extends VscElement { @property({type: Boolean, reflect: true, attribute: 'always-visible'}) alwaysVisible = false; + @property({type: Number, attribute: 'min-thumb-size'}) + minThumbSize = 40; + @property({type: Boolean, reflect: true}) shadow = true; @@ -29,7 +32,8 @@ export class VscodeScrollable extends VscElement { @property({type: Number, attribute: 'scroll-pos'}) set scrollPos(val: number) { - this._scrollPos = this._limitScrollPos(val); + this._scrollPos = val; + this._updateScrollbar(); this._updateThumbPosition(); this.requestUpdate(); } @@ -127,32 +131,26 @@ export class VscodeScrollable extends VscElement { private _resizeObserverCallback = () => { this._updateScrollbar(); + this._updateThumbPosition(); }; - private _limitScrollPos(pos: number) { - const minValue = 0; - let maxValue: number; - - if (this?.offsetHeight ?? 0 >= (this._contentElement?.offsetHeight ?? 0)) { - maxValue = 0; - } else { - maxValue = Math.max(0, this.offsetHeight - this._thumbHeight); - } - - console.log(minValue, maxValue); + private _calcThumbHeight() { + const componentHeight = this.offsetHeight; + const contentHeight = this._contentElement?.offsetHeight ?? 0; + const proposedSize = componentHeight * (componentHeight / contentHeight); - return Math.max(minValue, Math.min(maxValue, pos)); + return Math.max(this.minThumbSize, proposedSize); } private _updateScrollbar() { - const contentHeight = this._contentElement.offsetHeight; + const contentHeight = this._contentElement?.offsetHeight ?? 0; const componentHeight = this.offsetHeight; if (componentHeight >= contentHeight) { this._scrollbarVisible = false; } else { this._scrollbarVisible = true; - this._thumbHeight = componentHeight * (componentHeight / contentHeight); + this._thumbHeight = this._calcThumbHeight(); } this.requestUpdate(); @@ -200,6 +198,7 @@ export class VscodeScrollable extends VscElement { //#region event handlers private _handleSlotChange = () => { + this._updateScrollbar(); this._updateThumbPosition(); this._zIndexFix(); }; From c73b9667a3bdc964cf214b548a6bdc63dac791be Mon Sep 17 00:00:00 2001 From: bendera Date: Sun, 22 Jun 2025 23:17:31 +0200 Subject: [PATCH 14/33] Don't activate first option by default --- src/includes/vscode-select/OptionListController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/includes/vscode-select/OptionListController.ts b/src/includes/vscode-select/OptionListController.ts index 1fcb27991..99b2d7088 100644 --- a/src/includes/vscode-select/OptionListController.ts +++ b/src/includes/vscode-select/OptionListController.ts @@ -386,7 +386,7 @@ export class OptionListController implements ReactiveController { if (this._selectedIndex > -1) { this._activeIndex = this._selectedIndex; } else { - this._activeIndex = 0; + this._activeIndex = -1; } } From 2326258de03031224bd9e532d96b79d47bbc1bdc Mon Sep 17 00:00:00 2001 From: bendera Date: Sun, 22 Jun 2025 23:18:15 +0200 Subject: [PATCH 15/33] Add demos --- dev/vscode-scrollable/always-visible.html | 26 +++++++-- .../select-mode/scroll-demo.html | 54 +++++++++++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 dev/vscode-single-select/select-mode/scroll-demo.html diff --git a/dev/vscode-scrollable/always-visible.html b/dev/vscode-scrollable/always-visible.html index 6e3b8abd4..29d4bbcb1 100644 --- a/dev/vscode-scrollable/always-visible.html +++ b/dev/vscode-scrollable/always-visible.html @@ -3,10 +3,6 @@ - VSCode Elements Apply CSP ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae;

+

 

+

 

+

 

+

 

aaa
+
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam + volutpat ex sit amet venenatis auctor. Nunc semper consequat diam + sit amet eleifend. Ut a viverra nulla. Fusce vel sapien quis metus + vestibulum dignissim in sit amet orci. Sed lorem diam, scelerisque + non urna ac, egestas suscipit eros. Donec consequat tristique + lectus, quis placerat metus venenatis a. Nam fringilla lectus + finibus iaculis dictum. Maecenas in risus velit. Vestibulum ante + ipsum primis in faucibus orci luctus et ultrices posuere cubilia + curae; +

+

 

+

 

+

 

+

 

+
aaa
+
diff --git a/dev/vscode-single-select/select-mode/scroll-demo.html b/dev/vscode-single-select/select-mode/scroll-demo.html new file mode 100644 index 000000000..6c6f4ea4b --- /dev/null +++ b/dev/vscode-single-select/select-mode/scroll-demo.html @@ -0,0 +1,54 @@ + + + + + + VSCode Elements + + + + + + + +
+ + + Option 1 + Option 2 + Option 3 + Option 4 + Option 5 + Option 6 + Option 7 + Option 8 + Option 9 + Option 10 + Option 11 + Option 12 + Option 13 + Option 14 + Option 15 + Option 16 + Option 17 + Option 18 + Option 19 + Option 20 + + +
+ + From c1ef55d4115e10b3d62378dd041ccd4c39343fb2 Mon Sep 17 00:00:00 2001 From: bendera Date: Sun, 22 Jun 2025 23:18:22 +0200 Subject: [PATCH 16/33] Update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc46d7458..b62966ae3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ 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 + +- Added `alwaysVisible` property to **Scrollable**. + ## [1.16.1] - 2025-05-22 ### Fixed From 3a646fed875a5866c724f6d82917de480671556d Mon Sep 17 00:00:00 2001 From: bendera Date: Sun, 22 Jun 2025 23:21:25 +0200 Subject: [PATCH 17/33] Fix demo --- dev/vscode-single-select/select-mode/scroll-demo.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/vscode-single-select/select-mode/scroll-demo.html b/dev/vscode-single-select/select-mode/scroll-demo.html index 6c6f4ea4b..8d12ccd09 100644 --- a/dev/vscode-single-select/select-mode/scroll-demo.html +++ b/dev/vscode-single-select/select-mode/scroll-demo.html @@ -47,7 +47,7 @@ Option 18 Option 19 Option 20 - + From cb6004ed21ffe12d277d55d776107d0bfc84db0f Mon Sep 17 00:00:00 2001 From: bendera Date: Sun, 22 Jun 2025 23:24:19 +0200 Subject: [PATCH 18/33] FIx demos --- dev/vscode-scrollable/always-visible.html | 31 +++++++++---------- .../select-mode/scroll-demo.html | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/dev/vscode-scrollable/always-visible.html b/dev/vscode-scrollable/always-visible.html index 29d4bbcb1..b10bb5429 100644 --- a/dev/vscode-scrollable/always-visible.html +++ b/dev/vscode-scrollable/always-visible.html @@ -61,23 +61,22 @@

Apply CSP

aaa
-
+

- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam - volutpat ex sit amet venenatis auctor. Nunc semper consequat diam - sit amet eleifend. Ut a viverra nulla. Fusce vel sapien quis metus - vestibulum dignissim in sit amet orci. Sed lorem diam, scelerisque - non urna ac, egestas suscipit eros. Donec consequat tristique - lectus, quis placerat metus venenatis a. Nam fringilla lectus - finibus iaculis dictum. Maecenas in risus velit. Vestibulum ante - ipsum primis in faucibus orci luctus et ultrices posuere cubilia - curae; -

-

 

-

 

-

 

-

 

-
aaa
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam volutpat + ex sit amet venenatis auctor. Nunc semper consequat diam sit amet + eleifend. Ut a viverra nulla. Fusce vel sapien quis metus vestibulum + dignissim in sit amet orci. Sed lorem diam, scelerisque non urna ac, + egestas suscipit eros. Donec consequat tristique lectus, quis placerat + metus venenatis a. Nam fringilla lectus finibus iaculis dictum. + Maecenas in risus velit. Vestibulum ante ipsum primis in faucibus orci + luctus et ultrices posuere cubilia curae; +

+

 

+

 

+

 

+

 

+
aaa
diff --git a/dev/vscode-single-select/select-mode/scroll-demo.html b/dev/vscode-single-select/select-mode/scroll-demo.html index 8d12ccd09..3cc561687 100644 --- a/dev/vscode-single-select/select-mode/scroll-demo.html +++ b/dev/vscode-single-select/select-mode/scroll-demo.html @@ -48,7 +48,7 @@ Option 19 Option 20 - + From bbaba134c7de205844f2b64e731fba56b34f69e0 Mon Sep 17 00:00:00 2001 From: bendera Date: Mon, 23 Jun 2025 22:06:26 +0200 Subject: [PATCH 19/33] Fixes --- .../vscode-select/OptionListController.ts | 2 +- .../vscode-single-select.test.ts | 24 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/includes/vscode-select/OptionListController.ts b/src/includes/vscode-select/OptionListController.ts index 99b2d7088..1fcb27991 100644 --- a/src/includes/vscode-select/OptionListController.ts +++ b/src/includes/vscode-select/OptionListController.ts @@ -386,7 +386,7 @@ export class OptionListController implements ReactiveController { if (this._selectedIndex > -1) { this._activeIndex = this._selectedIndex; } else { - this._activeIndex = -1; + this._activeIndex = 0; } } diff --git a/src/vscode-single-select/vscode-single-select.test.ts b/src/vscode-single-select/vscode-single-select.test.ts index 91ebf6c69..4fe99a71e 100644 --- a/src/vscode-single-select/vscode-single-select.test.ts +++ b/src/vscode-single-select/vscode-single-select.test.ts @@ -4,6 +4,7 @@ import type {VscodeOption} from '../vscode-option/vscode-option.js'; import {VscodeSingleSelect} from './index.js'; import {aTimeout, expect, fixture, html} from '@open-wc/testing'; import sinon from 'sinon'; +import { VscodeScrollable } from '../main.js'; const ignoredAttributes = [ 'aria-label', @@ -266,8 +267,8 @@ describe('vscode-single-select', () => { await el.updateComplete; await sendKeys({press: 'Enter'}); - const options = el.shadowRoot?.querySelector('.options'); - expect(options?.scrollTop).to.eq(220); + const scrollable = el.shadowRoot?.querySelector('.scrollable'); + expect(scrollable?.scrollPos).to.eq(220); }); //#region keyboard interactions @@ -418,8 +419,9 @@ describe('vscode-single-select', () => { await el.updateComplete; const dropdown = el.shadowRoot?.querySelector('.dropdown'); + const scrollable = el.shadowRoot?.querySelector('.scrollable'); - expect(dropdown).lightDom.to.eq( + expect(scrollable).lightDom.to.eq( `
  • @@ -624,9 +626,9 @@ describe('vscode-single-select', () => { await clickOnElement(el); await sendKeys({type: 'Test'}); - const dropdown = el.shadowRoot?.querySelector('.dropdown'); + const scrollable = el.shadowRoot?.querySelector('.scrollable'); - expect(dropdown).lightDom.to.eq( + expect(scrollable).lightDom.to.eq( `
    • @@ -651,9 +653,9 @@ describe('vscode-single-select', () => { await el.updateComplete; await sendKeys({type: 'lo'}); - const dropdown = el.shadowRoot?.querySelector('.dropdown'); + const scrollable = el.shadowRoot?.querySelector('.scrollable'); - expect(dropdown).lightDom.to.eq( + expect(scrollable).lightDom.to.eq( `
      • @@ -684,9 +686,9 @@ describe('vscode-single-select', () => { await el.updateComplete; await sendKeys({type: 'Sit'}); - const dropdown = el.shadowRoot?.querySelector('.dropdown'); + const scrollable = el.shadowRoot?.querySelector('.scrollable'); - expect(dropdown).lightDom.to.eq( + expect(scrollable).lightDom.to.eq( `
        • Add "Sit"
        • @@ -714,9 +716,9 @@ describe('vscode-single-select', () => { await sendKeys({down: 'ArrowDown'}); await sendKeys({down: 'ArrowDown'}); - const dropdown = el.shadowRoot?.querySelector('.dropdown'); + const scrollable = el.shadowRoot?.querySelector('.scrollable'); - expect(dropdown).lightDom.to.eq( + expect(scrollable).lightDom.to.eq( `
          • Dolor
          • From 564005ed85b0cc6783a9441dfbb5b06b44ad9dc9 Mon Sep 17 00:00:00 2001 From: bendera Date: Mon, 23 Jun 2025 22:32:25 +0200 Subject: [PATCH 20/33] Change the default minThumbSize to 20 --- src/includes/vscode-select/vscode-select-base.ts | 1 + src/vscode-scrollable/vscode-scrollable.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/includes/vscode-select/vscode-select-base.ts b/src/includes/vscode-select/vscode-select-base.ts index 90958479e..cae4c16dc 100644 --- a/src/includes/vscode-select/vscode-select-base.ts +++ b/src/includes/vscode-select/vscode-select-base.ts @@ -758,6 +758,7 @@ export class VscodeSelectBase extends VscElement { Date: Thu, 26 Jun 2025 18:04:04 +0200 Subject: [PATCH 21/33] Implement scrolling based on the wheel event The scroll event did not detect scrolling when the mouse was over the scrollbar. --- dev/vscode-scrollable/always-visible.html | 3 +-- src/vscode-scrollable/vscode-scrollable.ts | 26 ++++++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/dev/vscode-scrollable/always-visible.html b/dev/vscode-scrollable/always-visible.html index b10bb5429..e865d38c6 100644 --- a/dev/vscode-scrollable/always-visible.html +++ b/dev/vscode-scrollable/always-visible.html @@ -39,11 +39,10 @@ -

            Apply CSP

            -

            +

            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam volutpat ex sit amet venenatis auctor. Nunc semper consequat diam sit amet eleifend. Ut a viverra nulla. Fusce vel sapien quis metus diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index 00e4d059c..5bc99c975 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -93,6 +93,7 @@ export class VscodeScrollable extends VscElement { super(); this.addEventListener('mouseover', this._handleComponentMouseOver); this.addEventListener('mouseout', this._handleComponentMouseOut); + this.addEventListener('wheel', this._handleComponentWheel); } override connectedCallback(): void { @@ -234,6 +235,12 @@ export class VscodeScrollable extends VscElement { this._thumbY = nextPos; this._scrollPos = (nextPos / (cmpH - thumbH)) * (contentH - cmpH); + + this.dispatchEvent( + new CustomEvent('vsc-scrollable-change', { + detail: this.scrollPos, + }) + ); }; private _handleScrollThumbMouseUp = (event: MouseEvent) => { @@ -269,11 +276,23 @@ export class VscodeScrollable extends VscElement { } }; - private _handleScroll = () => { - this._scrollPos = this._scrollableContainer.scrollTop; + private _handleComponentWheel = (ev: WheelEvent) => { + ev.stopPropagation(); + ev.preventDefault(); + + const calculatedNewPos = this.scrollPos + ev.deltaY; + + if (calculatedNewPos < 0) { + this.scrollPos = 0; + } else if (calculatedNewPos > this.scrollMax) { + this.scrollPos = this.scrollMax; + } else { + this.scrollPos = calculatedNewPos; + } + this.dispatchEvent( new CustomEvent('vsc-scrollable-change', { - detail: this._scrollPos, + detail: this.scrollPos, }) ); }; @@ -288,7 +307,6 @@ export class VscodeScrollable extends VscElement { userSelect: this._isDragging ? 'none' : 'auto', })} .scrollTop=${this._scrollPos} - @scroll=${this._handleScroll} >

            Date: Fri, 27 Jun 2025 18:06:26 +0200 Subject: [PATCH 22/33] Improve scrolling --- src/vscode-scrollable/vscode-scrollable.ts | 78 +++++++++++++--------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index 5bc99c975..9c372467d 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -107,10 +107,6 @@ export class VscodeScrollable extends VscElement { this.requestUpdate(); this.updateComplete.then(() => { - this._scrollableContainer.addEventListener( - 'scroll', - this._handleScrollableContainerScroll - ); this._hostResizeObserver.observe(this); this._contentResizeObserver.observe(this._contentElement); this._updateThumbPosition(); @@ -197,6 +193,38 @@ export class VscodeScrollable extends VscElement { this._thumbY = Math.min(ratio * (componentH - thumbH), thumbYMax); } + private _calculateScrollPosFromThumbPos(scrollPos: number) { + const cmpH = this.getBoundingClientRect().height; + const thumbH = this._scrollThumbElement.getBoundingClientRect().height; + const contentH = this._contentElement.getBoundingClientRect().height; + const rawScrollPos = (scrollPos / (cmpH - thumbH)) * (contentH - cmpH); + + return this._limitScrollPos(rawScrollPos); + } + + private _limitScrollPos(newPos: number) { + if (newPos < 0) { + return 0; + } else if (newPos > this.scrollMax) { + return this.scrollMax; + } else { + return newPos; + } + } + + private _limitThumbPos(newPos: number) { + const cmpH = this.getBoundingClientRect().height; + const thumbH = this._scrollThumbElement.getBoundingClientRect().height; + + if (newPos < 0) { + return 0; + } else if (newPos > cmpH - thumbH) { + return cmpH - thumbH; + } else { + return newPos; + } + } + //#region event handlers private _handleSlotChange = () => { this._updateScrollbar(); @@ -218,23 +246,10 @@ export class VscodeScrollable extends VscElement { } private _handleScrollThumbMouseMove = (event: MouseEvent) => { - const predictedPos = + const rawThumbPos = this._scrollThumbStartY + (event.screenY - this._mouseStartY); - let nextPos = 0; - const cmpH = this.getBoundingClientRect().height; - const thumbH = this._scrollThumbElement.getBoundingClientRect().height; - const contentH = this._contentElement.getBoundingClientRect().height; - - if (predictedPos < 0) { - nextPos = 0; - } else if (predictedPos > cmpH - thumbH) { - nextPos = cmpH - thumbH; - } else { - nextPos = predictedPos; - } - - this._thumbY = nextPos; - this._scrollPos = (nextPos / (cmpH - thumbH)) * (contentH - cmpH); + this._thumbY = this._limitThumbPos(rawThumbPos); + this.scrollPos = this._calculateScrollPosFromThumbPos(this._thumbY); this.dispatchEvent( new CustomEvent('vsc-scrollable-change', { @@ -277,19 +292,9 @@ export class VscodeScrollable extends VscElement { }; private _handleComponentWheel = (ev: WheelEvent) => { - ev.stopPropagation(); ev.preventDefault(); - const calculatedNewPos = this.scrollPos + ev.deltaY; - - if (calculatedNewPos < 0) { - this.scrollPos = 0; - } else if (calculatedNewPos > this.scrollMax) { - this.scrollPos = this.scrollMax; - } else { - this.scrollPos = calculatedNewPos; - } - + this.scrollPos = this._limitScrollPos(this.scrollPos + ev.deltaY); this.dispatchEvent( new CustomEvent('vsc-scrollable-change', { detail: this.scrollPos, @@ -297,6 +302,15 @@ export class VscodeScrollable extends VscElement { ); }; + private _handleScrollbarTrackPress(ev: PointerEvent) { + if (ev.target !== ev.currentTarget) { + return; + } + + this._thumbY = ev.offsetY - this._thumbHeight / 2; + this.scrollPos = this._calculateScrollPosFromThumbPos(this._thumbY); + } + //#endregion override render(): TemplateResult { @@ -307,6 +321,7 @@ export class VscodeScrollable extends VscElement { userSelect: this._isDragging ? 'none' : 'auto', })} .scrollTop=${this._scrollPos} + @scroll=${this._handleScrollableContainerScroll} >
            Date: Fri, 27 Jun 2025 20:45:03 +0200 Subject: [PATCH 23/33] Sync scroll position --- src/vscode-scrollable/vscode-scrollable.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index 9c372467d..c18fd8561 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -275,10 +275,6 @@ export class VscodeScrollable extends VscElement { document.removeEventListener('mouseup', this._handleScrollThumbMouseUp); }; - private _handleScrollableContainerScroll = () => { - this._updateThumbPosition(); - }; - private _handleComponentMouseOver = () => { this._thumbVisible = true; this._thumbFade = false; @@ -311,6 +307,12 @@ export class VscodeScrollable extends VscElement { this.scrollPos = this._calculateScrollPosFromThumbPos(this._thumbY); } + private _handleScrollableContainerScroll = (ev: Event) => { + if (ev.currentTarget) { + this.scrollPos = (ev.currentTarget as HTMLDivElement).scrollTop; + } + }; + //#endregion override render(): TemplateResult { From de9a59b37896dd30427711d6f0bad3bfb8ec352e Mon Sep 17 00:00:00 2001 From: bendera Date: Fri, 27 Jun 2025 21:32:28 +0200 Subject: [PATCH 24/33] Add sensitivity modifier properties --- src/vscode-scrollable/vscode-scrollable.ts | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index c18fd8561..f514b6f4a 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -21,9 +21,26 @@ export class VscodeScrollable extends VscElement { @property({type: Boolean, reflect: true, attribute: 'always-visible'}) alwaysVisible = false; + /** + * Scrolling speed multiplier when pressing `Alt`. This property is designed to use the value of + * `editor.fastScrollSensitivity`, `workbench.list.fastScrollSensitivity` or + * `terminal.integrated.fastScrollSensitivity` depending on the context. + */ + @property({type: Number, attribute: 'fast-scroll-sensitivity'}) + fastScrollSensitivity = 5; + @property({type: Number, attribute: 'min-thumb-size'}) minThumbSize = 20; + /** + * A multiplier to be used on the `deltaY` of the mouse wheel scroll events. This property is + * designed to use the value of `editor.mouseWheelScrollSensitivity`, + * `workbench.list.mouseWheelScrollSensitivity` or + * `terminal.integrated.mouseWheelScrollSensitivity` depending on the context. + */ + @property({type: Number, attribute: 'mouse-wheel-scroll-sensitivity'}) + mouseWheelScrollSensitivity = 1; + @property({type: Boolean, reflect: true}) shadow = true; @@ -290,7 +307,13 @@ export class VscodeScrollable extends VscElement { private _handleComponentWheel = (ev: WheelEvent) => { ev.preventDefault(); - this.scrollPos = this._limitScrollPos(this.scrollPos + ev.deltaY); + const multiplier = ev.altKey + ? this.mouseWheelScrollSensitivity * this.fastScrollSensitivity + : this.mouseWheelScrollSensitivity; + + this.scrollPos = this._limitScrollPos( + this.scrollPos + ev.deltaY * multiplier + ); this.dispatchEvent( new CustomEvent('vsc-scrollable-change', { detail: this.scrollPos, From b4657ba5387d5100414406c4dedb7474753b221f Mon Sep 17 00:00:00 2001 From: bendera Date: Fri, 27 Jun 2025 21:33:27 +0200 Subject: [PATCH 25/33] Prevent appearing useless outline --- src/includes/vscode-select/styles.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/includes/vscode-select/styles.ts b/src/includes/vscode-select/styles.ts index ffb82a50f..c45ab2cb5 100644 --- a/src/includes/vscode-select/styles.ts +++ b/src/includes/vscode-select/styles.ts @@ -193,6 +193,7 @@ export default [ display: block; max-height: 222px; margin: 1px 0; + outline: none; overflow: hidden; } From 79a1314b84055c7c1eb1f705877ec8bb3041407b Mon Sep 17 00:00:00 2001 From: bendera Date: Fri, 27 Jun 2025 21:52:28 +0200 Subject: [PATCH 26/33] Prettier fix --- dev/vscode-scrollable/always-visible.html | 2 +- src/vscode-single-select/vscode-single-select.test.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dev/vscode-scrollable/always-visible.html b/dev/vscode-scrollable/always-visible.html index e865d38c6..dc09270e1 100644 --- a/dev/vscode-scrollable/always-visible.html +++ b/dev/vscode-scrollable/always-visible.html @@ -42,7 +42,7 @@
            -

            +

            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam volutpat ex sit amet venenatis auctor. Nunc semper consequat diam sit amet eleifend. Ut a viverra nulla. Fusce vel sapien quis metus diff --git a/src/vscode-single-select/vscode-single-select.test.ts b/src/vscode-single-select/vscode-single-select.test.ts index 4fe99a71e..14d9f73e1 100644 --- a/src/vscode-single-select/vscode-single-select.test.ts +++ b/src/vscode-single-select/vscode-single-select.test.ts @@ -4,7 +4,7 @@ import type {VscodeOption} from '../vscode-option/vscode-option.js'; import {VscodeSingleSelect} from './index.js'; import {aTimeout, expect, fixture, html} from '@open-wc/testing'; import sinon from 'sinon'; -import { VscodeScrollable } from '../main.js'; +import {VscodeScrollable} from '../main.js'; const ignoredAttributes = [ 'aria-label', @@ -267,7 +267,8 @@ describe('vscode-single-select', () => { await el.updateComplete; await sendKeys({press: 'Enter'}); - const scrollable = el.shadowRoot?.querySelector('.scrollable'); + const scrollable = + el.shadowRoot?.querySelector('.scrollable'); expect(scrollable?.scrollPos).to.eq(220); }); From bbb92e7900c115f93bfaa4a7710e80c46b16471e Mon Sep 17 00:00:00 2001 From: bendera Date: Wed, 2 Jul 2025 17:26:19 +0200 Subject: [PATCH 27/33] Add tests --- .../vscode-multi-select.test.ts | 31 +++++++++++++++++-- .../vscode-single-select.test.ts | 27 ++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/vscode-multi-select/vscode-multi-select.test.ts b/src/vscode-multi-select/vscode-multi-select.test.ts index 9d69724b9..138b027bf 100644 --- a/src/vscode-multi-select/vscode-multi-select.test.ts +++ b/src/vscode-multi-select/vscode-multi-select.test.ts @@ -1,9 +1,10 @@ -import {VscodeMultiSelect} from './index.js'; import {expect, fixture, html} from '@open-wc/testing'; +import {sendKeys} from '@web/test-runner-commands'; import sinon from 'sinon'; import '../vscode-option/index.js'; import {clickOnElement, moveMouseOnElement} from '../includes/test-helpers.js'; import {VscodeOption} from '../vscode-option/index.js'; +import {VscodeMultiSelect} from './index.js'; describe('vscode-multi-select', () => { it('is defined', () => { @@ -351,9 +352,35 @@ describe('vscode-multi-select', () => { expect(isValidAfter).to.be.false; }); + it('creates and select suggested option', async () => { + const el = await fixture( + html`Lorem` + ); + const createOptionHandlerSpy = sinon.spy(); + el.addEventListener( + 'vsc-multi-select-create-option', + createOptionHandlerSpy + ); + const changeHandlerSpy = sinon.spy(); + el.addEventListener('change', changeHandlerSpy); + + el.focus(); + await el.updateComplete; + await sendKeys({type: 'asdf'}); + await sendKeys({down: 'ArrowDown'}); + await sendKeys({down: 'Enter'}); + + expect(createOptionHandlerSpy.getCalls()[0].args[0].detail.value).to.eq( + 'asdf' + ); + expect(changeHandlerSpy.called).to.be.true; + expect(el.value).to.eql(['asdf']); + }); + it('selects multiple options with keyboard'); it('selectedIndexes sync with values'); - it('creates and select suggested option (enter key press)'); it( 'dispatch change event, set form value, manage required state (enter key press)' ); diff --git a/src/vscode-single-select/vscode-single-select.test.ts b/src/vscode-single-select/vscode-single-select.test.ts index 14d9f73e1..5d569409a 100644 --- a/src/vscode-single-select/vscode-single-select.test.ts +++ b/src/vscode-single-select/vscode-single-select.test.ts @@ -1157,6 +1157,33 @@ describe('vscode-single-select', () => { it('End is pressed'); }); + it('creates and select suggested option', async () => { + const el = await fixture( + html`Lorem` + ); + const createOptionHandlerSpy = sinon.spy(); + el.addEventListener( + 'vsc-single-select-create-option', + createOptionHandlerSpy + ); + const changeHandlerSpy = sinon.spy(); + el.addEventListener('change', changeHandlerSpy); + + el.focus(); + await el.updateComplete; + await sendKeys({type: 'asdf'}); + await sendKeys({down: 'ArrowDown'}); + await sendKeys({down: 'Enter'}); + + expect(createOptionHandlerSpy.getCalls()[0].args[0].detail.value).to.eq( + 'asdf' + ); + expect(changeHandlerSpy.called).to.be.true; + expect(el.value).to.eql('asdf'); + }); + //keyboard navigation it('selects previous option with keyboard'); it('selects next option with keyboard'); From 9b9ca7b9b2a12c634ebd09a01e6985796cfcd323 Mon Sep 17 00:00:00 2001 From: bendera Date: Wed, 2 Jul 2025 17:26:48 +0200 Subject: [PATCH 28/33] Fix the create option event handler --- src/vscode-multi-select/vscode-multi-select.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vscode-multi-select/vscode-multi-select.ts b/src/vscode-multi-select/vscode-multi-select.ts index 52813571e..cc3e0b649 100644 --- a/src/vscode-multi-select/vscode-multi-select.ts +++ b/src/vscode-multi-select/vscode-multi-select.ts @@ -237,7 +237,7 @@ export class VscodeMultiSelect this._dispatchChangeEvent(); const opCreateEvent: VscMultiSelectCreateOptionEvent = new CustomEvent( 'vsc-multi-select-create-option', - {detail: {value: this._options[nextIndex]?.value ?? ''}} + {detail: {value: this._opts.getOptionByIndex(nextIndex)?.value ?? ''}} ); this.dispatchEvent(opCreateEvent); this.open = false; From 828df5e51a9925fae66d9b1b5966b9c025189b2a Mon Sep 17 00:00:00 2001 From: bendera Date: Wed, 2 Jul 2025 18:10:36 +0200 Subject: [PATCH 29/33] Update changelog --- CHANGELOG.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b62966ae3..5f1860e90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased] -## Added +### Added + +- Added `alwaysVisible`, `scrollSensitivity`, `fastScrollSensitivity` and `minThumbSize` property to **Scrollable**. +- **Scrollable** now dispatches the `vsc-scrollable-scroll` event. +- Added nicer checkboxes to **MultiSelect**. +- Added `selectAll()` and `selectNone()` methods to **MultiSelect**. +- Added a themed scrollbar to the **SingleSelect** and **MultiSelect**. + +### Changed + +- **ButtonGroup** can now shrink inside a flex container. +- **SingleSelect** and **MultiSelect** accessibility has been improved. +- **MultiSelect**: The badge displaying the number of selected options is now more compact. +- The 'Select all', 'Select none', and 'Accept' buttons have been removed from the **MultiSelect** dropdown for improved accessibility and better maintainability. + +### Fixed -- Added `alwaysVisible` property to **Scrollable**. +- **Label** can now be associated with **SingleSelect** and **MultiSelect**. ## [1.16.1] - 2025-05-22 From 0d2596a05e41ac2a1816afc4c27a117e9b4768b7 Mon Sep 17 00:00:00 2001 From: bendera Date: Wed, 2 Jul 2025 18:11:21 +0200 Subject: [PATCH 30/33] Rename Scrollable custom event, add type definitions --- src/includes/vscode-select/styles.ts | 4 ++-- src/includes/vscode-select/vscode-select-base.ts | 2 +- src/vscode-scrollable/vscode-scrollable.ts | 10 ++++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/includes/vscode-select/styles.ts b/src/includes/vscode-select/styles.ts index c45ab2cb5..7976a3e1d 100644 --- a/src/includes/vscode-select/styles.ts +++ b/src/includes/vscode-select/styles.ts @@ -192,7 +192,7 @@ export default [ .scrollable { display: block; max-height: 222px; - margin: 1px 0; + margin: 1px; outline: none; overflow: hidden; } @@ -202,7 +202,7 @@ export default [ cursor: pointer; list-style: none; margin: 0; - padding: 0 1px; + padding: 0; } .option { diff --git a/src/includes/vscode-select/vscode-select-base.ts b/src/includes/vscode-select/vscode-select-base.ts index cae4c16dc..9efd8c683 100644 --- a/src/includes/vscode-select/vscode-select-base.ts +++ b/src/includes/vscode-select/vscode-select-base.ts @@ -760,7 +760,7 @@ export class VscodeSelectBase extends VscElement { class="scrollable" min-thumb-size="40" tabindex="-1" - @vsc-scrollable-change=${this._onOptionListScroll} + @vsc-scrollable-scroll=${this._onOptionListScroll} .scrollPos=${this._optionListScrollPos} .style=${stylePropertyMap({ height: `${scrollPaneHeight}px`, diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index f514b6f4a..3e9a6a6bf 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -5,6 +5,8 @@ import {customElement, VscElement} from '../includes/VscElement.js'; import {stylePropertyMap} from '../includes/style-property-map.js'; import styles from './vscode-scrollable.styles.js'; +export type VscScrollableScrollEvent = CustomEvent; + /** * @tag vscode-scrollable * @@ -269,7 +271,7 @@ export class VscodeScrollable extends VscElement { this.scrollPos = this._calculateScrollPosFromThumbPos(this._thumbY); this.dispatchEvent( - new CustomEvent('vsc-scrollable-change', { + new CustomEvent('vsc-scrollable-scroll', { detail: this.scrollPos, }) ); @@ -315,7 +317,7 @@ export class VscodeScrollable extends VscElement { this.scrollPos + ev.deltaY * multiplier ); this.dispatchEvent( - new CustomEvent('vsc-scrollable-change', { + new CustomEvent('vsc-scrollable-scroll', { detail: this.scrollPos, }) ); @@ -390,4 +392,8 @@ declare global { interface HTMLElementTagNameMap { 'vscode-scrollable': VscodeScrollable; } + + interface GlobalEventHandlersEventMap { + 'vsc-scrollable-scroll': VscScrollableScrollEvent; + } } From 44bbd1da18dce98c21a0b446d322e258969cc8ad Mon Sep 17 00:00:00 2001 From: bendera Date: Wed, 2 Jul 2025 22:59:14 +0200 Subject: [PATCH 31/33] Add tests --- .../vscode-scrollable.test.ts | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/vscode-scrollable/vscode-scrollable.test.ts b/src/vscode-scrollable/vscode-scrollable.test.ts index 8f9b53bcc..b42c09325 100644 --- a/src/vscode-scrollable/vscode-scrollable.test.ts +++ b/src/vscode-scrollable/vscode-scrollable.test.ts @@ -1,9 +1,64 @@ +import {resetMouse} from '@web/test-runner-commands'; +import {dragElement} from '../includes/test-helpers.js'; import {VscodeScrollable} from './index.js'; -import {expect} from '@open-wc/testing'; +import {expect, fixture, html} from '@open-wc/testing'; +import sinon from 'sinon'; describe('vscode-scrollable', () => { it('is defined', () => { const el = document.createElement('vscode-scrollable'); expect(el).to.instanceOf(VscodeScrollable); }); + + it('initializes scrollbar', async () => { + const el = await fixture( + html`

            ` + ); + + const thumb = + el.shadowRoot!.querySelector('.scrollbar-thumb'); + + expect(thumb?.offsetHeight).to.eq(50); + expect(thumb?.offsetTop).to.eq(0); + expect(el.scrollPos).to.eq(0); + }); + + it('drags thumb', async () => { + const el = await fixture( + html`
            ` + ); + const scrollEventSpy = sinon.spy(); + el.addEventListener('vsc-scrollable-scroll', scrollEventSpy); + + const thumb = el.shadowRoot!.querySelector( + '.scrollbar-thumb' + ) as HTMLDivElement; + + await dragElement(thumb, 0, 25); + await resetMouse(); + + expect(el.scrollPos).to.eq(50); + expect(scrollEventSpy.called).to.be.true; + }); + + it('scrolls content', async () => { + const el = await fixture( + html`
            ` + ); + const scrollEventSpy = sinon.spy(); + el.addEventListener('vsc-scrollable-scroll', scrollEventSpy); + + const wheelEvent = new WheelEvent('wheel', {deltaY: 55}); + el.dispatchEvent(wheelEvent); + await el.updateComplete; + + expect(el.scrollPos).to.eq(55); + expect(scrollEventSpy.called).to.be.true; + }); }); From 90921cba5c313b187a9750a645ab6cae03a5792c Mon Sep 17 00:00:00 2001 From: bendera Date: Wed, 2 Jul 2025 23:22:52 +0200 Subject: [PATCH 32/33] Add custom elements manifest deprecator --- custom-elements-manifest.config.mjs | 7 +++++++ package-lock.json | 20 ++++++++++++++++++++ package.json | 1 + 3 files changed, 28 insertions(+) create mode 100644 custom-elements-manifest.config.mjs diff --git a/custom-elements-manifest.config.mjs b/custom-elements-manifest.config.mjs new file mode 100644 index 000000000..2ed209ab5 --- /dev/null +++ b/custom-elements-manifest.config.mjs @@ -0,0 +1,7 @@ +import {cemDeprecatorPlugin} from 'custom-elements-manifest-deprecator'; + +const options = {}; + +export default { + plugins: [cemDeprecatorPlugin(options)], +}; diff --git a/package-lock.json b/package-lock.json index b3e011d97..b59c63c1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ "chokidar": "^4.0.3", "concurrently": "^9.1.2", "custom-element-vs-code-integration": "^1.5.0", + "custom-elements-manifest-deprecator": "^1.2.0", "deepmerge": "^4.3.1", "dotenv": "^16.4.7", "eslint-plugin-lit": "^2.0.0", @@ -5849,6 +5850,16 @@ "integrity": "sha512-j59k0ExGCKA8T6Mzaq+7axc+KVHwpEphEERU7VZ99260npu/p/9kd+Db+I3cGKxHkM5y6q5gnlXn00mzRQkX2A==", "dev": true }, + "node_modules/custom-elements-manifest-deprecator": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/custom-elements-manifest-deprecator/-/custom-elements-manifest-deprecator-1.2.0.tgz", + "integrity": "sha512-6dKX6ELfEC8BsccFuUtLQRX+X1ODXNxPNODeudyyYkWD3eBcolzehQjTivLPBx7FSHFi5BdwV2D4lwr8P7ifbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@prettier/sync": "^0.5.2" + } + }, "node_modules/data-uri-to-buffer": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", @@ -15871,6 +15882,15 @@ "integrity": "sha512-j59k0ExGCKA8T6Mzaq+7axc+KVHwpEphEERU7VZ99260npu/p/9kd+Db+I3cGKxHkM5y6q5gnlXn00mzRQkX2A==", "dev": true }, + "custom-elements-manifest-deprecator": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/custom-elements-manifest-deprecator/-/custom-elements-manifest-deprecator-1.2.0.tgz", + "integrity": "sha512-6dKX6ELfEC8BsccFuUtLQRX+X1ODXNxPNODeudyyYkWD3eBcolzehQjTivLPBx7FSHFi5BdwV2D4lwr8P7ifbw==", + "dev": true, + "requires": { + "@prettier/sync": "^0.5.2" + } + }, "data-uri-to-buffer": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", diff --git a/package.json b/package.json index 41e0465e0..c83dfb4eb 100644 --- a/package.json +++ b/package.json @@ -164,6 +164,7 @@ "chokidar": "^4.0.3", "concurrently": "^9.1.2", "custom-element-vs-code-integration": "^1.5.0", + "custom-elements-manifest-deprecator": "^1.2.0", "deepmerge": "^4.3.1", "dotenv": "^16.4.7", "eslint-plugin-lit": "^2.0.0", From 9fa4304794fd76bcf6629886a0ae4f94b00d53b2 Mon Sep 17 00:00:00 2001 From: bendera Date: Wed, 2 Jul 2025 23:27:45 +0200 Subject: [PATCH 33/33] Update docs --- src/vscode-scrollable/vscode-scrollable.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/vscode-scrollable/vscode-scrollable.ts b/src/vscode-scrollable/vscode-scrollable.ts index 3e9a6a6bf..5393e8a3c 100644 --- a/src/vscode-scrollable/vscode-scrollable.ts +++ b/src/vscode-scrollable/vscode-scrollable.ts @@ -10,7 +10,7 @@ export type VscScrollableScrollEvent = CustomEvent; /** * @tag vscode-scrollable * - * @cssprop [--min-thumb-height=20px] - Scrollbar thumb minimum height + * @cssprop --min-thumb-height - (@deprecated) This css property is deprecated. Use the `minThumbSize` property instead. * @cssprop [--vscode-scrollbar-shadow=#000000] * @cssprop [--vscode-scrollbarSlider-background=rgba(121, 121, 121, 0.4)] * @cssprop [--vscode-scrollbarSlider-hoverBackground=rgba(100, 100, 100, 0.7)] @@ -20,6 +20,10 @@ export type VscScrollableScrollEvent = CustomEvent; export class VscodeScrollable extends VscElement { static override styles = styles; + /** + * By default, the scrollbar appears only when the cursor hovers over the + * component. With this option, the scrollbar will always be visible. + */ @property({type: Boolean, reflect: true, attribute: 'always-visible'}) alwaysVisible = false; @@ -31,6 +35,9 @@ export class VscodeScrollable extends VscElement { @property({type: Number, attribute: 'fast-scroll-sensitivity'}) fastScrollSensitivity = 5; + /** + * This setting defines the scrollbar's minimum size when the component contains a large amount of content. + */ @property({type: Number, attribute: 'min-thumb-size'}) minThumbSize = 20; @@ -43,12 +50,21 @@ export class VscodeScrollable extends VscElement { @property({type: Number, attribute: 'mouse-wheel-scroll-sensitivity'}) mouseWheelScrollSensitivity = 1; + /** + * Controls shadow visibility when content overflows. + */ @property({type: Boolean, reflect: true}) shadow = true; + /** + * It's true when `scrollPos` greater than 0 + */ @property({type: Boolean, reflect: true}) scrolled = false; + /** + * Scroll position. + */ @property({type: Number, attribute: 'scroll-pos'}) set scrollPos(val: number) { this._scrollPos = val; @@ -62,6 +78,9 @@ export class VscodeScrollable extends VscElement { private _scrollPos = 0; + /** + * The maximum amount of the `scrollPos`. + */ @property({type: Number, attribute: 'scroll-max'}) get scrollMax(): number { if (!this._scrollableContainer) {