kopia lustrzana https://github.com/shoelace-style/shoelace
Add no-scroll-controls prop; fixes #253
rodzic
3920d18286
commit
f11b4b53d0
docs/getting-started
src
components/tab-group
|
@ -8,6 +8,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
|
|||
|
||||
## Next
|
||||
|
||||
- Added `no-scroll-controls` prop to `sl-tab-group`
|
||||
- Fixed a bug where `disabled` could be set when buttons are rendered as links
|
||||
- Fixed a bug where hoisted dropdowns would render in the wrong position when place inside an `sl-dialog`
|
||||
- Improved `sl-dropdown` accessibility by attaching `aria-haspopup` and `aria-expanded` to the slotted trigger
|
||||
|
|
|
@ -992,6 +992,10 @@ export namespace Components {
|
|||
"setFocus": () => Promise<void>;
|
||||
}
|
||||
interface SlTabGroup {
|
||||
/**
|
||||
* Disables the scroll arrows that appear when tabs overflow.
|
||||
*/
|
||||
"noScrollControls": boolean;
|
||||
/**
|
||||
* The placement of the tabs.
|
||||
*/
|
||||
|
@ -2481,6 +2485,10 @@ declare namespace LocalJSX {
|
|||
"panel"?: string;
|
||||
}
|
||||
interface SlTabGroup {
|
||||
/**
|
||||
* Disables the scroll arrows that appear when tabs overflow.
|
||||
*/
|
||||
"noScrollControls"?: boolean;
|
||||
/**
|
||||
* Emitted when a tab is hidden.
|
||||
*/
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.tab-group--horizontal-scroll .tab-group__nav-container {
|
||||
.tab-group--has-scroll-controls .tab-group__nav-container {
|
||||
position: relative;
|
||||
padding: 0 var(--sl-spacing-x-large);
|
||||
}
|
||||
|
|
|
@ -35,16 +35,24 @@ export class TabGroup {
|
|||
|
||||
@Element() host: HTMLSlTabGroupElement;
|
||||
|
||||
@State() canScrollHorizontally = false;
|
||||
@State() hasScrollControls = false;
|
||||
|
||||
/** The placement of the tabs. */
|
||||
@Prop() placement: 'top' | 'bottom' | 'left' | 'right' = 'top';
|
||||
|
||||
/** Disables the scroll arrows that appear when tabs overflow. */
|
||||
@Prop() noScrollControls = false;
|
||||
|
||||
@Watch('placement')
|
||||
handlePlacementChange() {
|
||||
this.syncActiveTabIndicator();
|
||||
}
|
||||
|
||||
@Watch('noScrollControls')
|
||||
handleNoScrollControlsChange() {
|
||||
this.updateScrollControls();
|
||||
}
|
||||
|
||||
/** Emitted when a tab is shown. */
|
||||
@Event({ eventName: 'sl-tab-show' }) slTabShow: EventEmitter<{ name: string }>;
|
||||
|
||||
|
@ -71,9 +79,9 @@ export class TabGroup {
|
|||
|
||||
focusVisible.observe(this.tabGroup);
|
||||
|
||||
this.resizeObserver = new ResizeObserver(() => this.syncHorizontalScroll());
|
||||
this.resizeObserver = new ResizeObserver(() => this.updateScrollControls());
|
||||
this.resizeObserver.observe(this.nav);
|
||||
requestAnimationFrame(() => this.syncHorizontalScroll());
|
||||
requestAnimationFrame(() => this.updateScrollControls());
|
||||
|
||||
// Update aria labels if the DOM changes
|
||||
this.mutationObserver = new MutationObserver(mutations => {
|
||||
|
@ -189,6 +197,15 @@ export class TabGroup {
|
|||
});
|
||||
}
|
||||
|
||||
updateScrollControls() {
|
||||
if (this.noScrollControls) {
|
||||
this.hasScrollControls = false;
|
||||
} else {
|
||||
this.hasScrollControls =
|
||||
['top', 'bottom'].includes(this.placement) && this.nav.scrollWidth > this.nav.clientWidth;
|
||||
}
|
||||
}
|
||||
|
||||
setActiveTab(tab: HTMLSlTabElement, emitEvents = true) {
|
||||
if (tab && tab !== this.activeTab && !tab.disabled) {
|
||||
const previousTab = this.activeTab;
|
||||
|
@ -253,11 +270,6 @@ export class TabGroup {
|
|||
}
|
||||
}
|
||||
|
||||
syncHorizontalScroll() {
|
||||
this.canScrollHorizontally =
|
||||
['top', 'bottom'].includes(this.placement) && this.nav.scrollWidth > this.nav.clientWidth;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
|
@ -272,13 +284,13 @@ export class TabGroup {
|
|||
'tab-group--left': this.placement === 'left',
|
||||
'tab-group--right': this.placement === 'right',
|
||||
|
||||
'tab-group--horizontal-scroll': this.canScrollHorizontally
|
||||
'tab-group--has-scroll-controls': this.hasScrollControls
|
||||
}}
|
||||
onClick={this.handleClick}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
>
|
||||
<div class="tab-group__nav-container">
|
||||
{this.canScrollHorizontally && (
|
||||
{this.hasScrollControls && (
|
||||
<sl-icon-button
|
||||
class="tab-group__scroll-button tab-group__scroll-button--left"
|
||||
name="chevron-left"
|
||||
|
@ -295,7 +307,7 @@ export class TabGroup {
|
|||
<slot name="nav" />
|
||||
</div>
|
||||
</div>
|
||||
{this.canScrollHorizontally && (
|
||||
{this.hasScrollControls && (
|
||||
<sl-icon-button
|
||||
class="tab-group__scroll-button tab-group__scroll-button--right"
|
||||
name="chevron-right"
|
||||
|
|
Ładowanie…
Reference in New Issue