kopia lustrzana https://github.com/shoelace-style/shoelace
fix RTL in breadcrumb, tab group, and split panel
rodzic
4c3313e275
commit
d0ff2fef35
|
|
@ -1,6 +1,7 @@
|
|||
import { html, LitElement } from 'lit';
|
||||
import { customElement, property, query } from 'lit/decorators.js';
|
||||
import '../../components/icon/icon';
|
||||
import { LocalizeController } from '../../utilities/localize';
|
||||
import styles from './breadcrumb.styles';
|
||||
import type SlBreadcrumbItem from '../../components/breadcrumb-item/breadcrumb-item';
|
||||
|
||||
|
|
@ -22,6 +23,9 @@ export default class SlBreadcrumb extends LitElement {
|
|||
@query('slot') defaultSlot: HTMLSlotElement;
|
||||
@query('slot[name="separator"]') separatorSlot: HTMLSlotElement;
|
||||
|
||||
private readonly localize = new LocalizeController(this);
|
||||
private separatorDir = this.localize.dir();
|
||||
|
||||
/**
|
||||
* The label to use for the breadcrumb control. This will not be shown, but it will be announced by screen readers and
|
||||
* other assistive devices.
|
||||
|
|
@ -35,6 +39,7 @@ export default class SlBreadcrumb extends LitElement {
|
|||
// Clone it, remove ids, and slot it
|
||||
const clone = separator.cloneNode(true) as HTMLElement;
|
||||
[clone, ...clone.querySelectorAll('[id]')].forEach(el => el.removeAttribute('id'));
|
||||
clone.setAttribute('data-default', '');
|
||||
clone.slot = 'separator';
|
||||
|
||||
return clone;
|
||||
|
|
@ -49,7 +54,13 @@ export default class SlBreadcrumb extends LitElement {
|
|||
// Append separators to each item if they don't already have one
|
||||
const separator = item.querySelector('[slot="separator"]');
|
||||
if (separator === null) {
|
||||
// No separator exists, add one
|
||||
item.append(this.getSeparator());
|
||||
} else if (separator.hasAttribute('data-default')) {
|
||||
// A default separator exists, replace it
|
||||
separator.replaceWith(this.getSeparator());
|
||||
} else {
|
||||
// The user provided a custom separator, leave it alone
|
||||
}
|
||||
|
||||
// The last breadcrumb item is the "current page"
|
||||
|
|
@ -62,13 +73,21 @@ export default class SlBreadcrumb extends LitElement {
|
|||
}
|
||||
|
||||
render() {
|
||||
// We clone the separator and inject them into breadcrumb items, so we need to regenerate the default ones when
|
||||
// directionality changes. We do this by storing the current separator direction, waiting for render, then calling
|
||||
// the function that regenerates them.
|
||||
if (this.separatorDir !== this.localize.dir()) {
|
||||
this.separatorDir = this.localize.dir();
|
||||
this.updateComplete.then(() => this.handleSlotChange());
|
||||
}
|
||||
|
||||
return html`
|
||||
<nav part="base" class="breadcrumb" aria-label=${this.label}>
|
||||
<slot @slotchange=${this.handleSlotChange}></slot>
|
||||
</nav>
|
||||
|
||||
<slot name="separator" hidden aria-hidden="true">
|
||||
<sl-icon name="chevron-right" library="system"></sl-icon>
|
||||
<sl-icon name=${this.localize.dir() === 'rtl' ? 'chevron-left' : 'chevron-right'} library="system"></sl-icon>
|
||||
</slot>
|
||||
`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ export default class SlSplitPanel extends LitElement {
|
|||
}
|
||||
|
||||
handleDrag(event: PointerEvent) {
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -130,6 +132,10 @@ export default class SlSplitPanel extends LitElement {
|
|||
snapPoint = parseFloat(value);
|
||||
}
|
||||
|
||||
if (isRtl && !this.vertical) {
|
||||
snapPoint = this.size - snapPoint;
|
||||
}
|
||||
|
||||
if (
|
||||
newPositionInPixels >= snapPoint - this.snapThreshold &&
|
||||
newPositionInPixels <= snapPoint + this.snapThreshold
|
||||
|
|
@ -206,6 +212,7 @@ export default class SlSplitPanel extends LitElement {
|
|||
render() {
|
||||
const gridTemplate = this.vertical ? 'gridTemplateRows' : 'gridTemplateColumns';
|
||||
const gridTemplateAlt = this.vertical ? 'gridTemplateColumns' : 'gridTemplateRows';
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
const primary = `
|
||||
clamp(
|
||||
0%,
|
||||
|
|
@ -220,9 +227,17 @@ export default class SlSplitPanel extends LitElement {
|
|||
const secondary = 'auto';
|
||||
|
||||
if (this.primary === 'end') {
|
||||
this.style[gridTemplate] = `${secondary} var(--divider-width) ${primary}`;
|
||||
if (isRtl && !this.vertical) {
|
||||
this.style[gridTemplate] = `${primary} var(--divider-width) ${secondary}`;
|
||||
} else {
|
||||
this.style[gridTemplate] = `${secondary} var(--divider-width) ${primary}`;
|
||||
}
|
||||
} else {
|
||||
this.style[gridTemplate] = `${primary} var(--divider-width) ${secondary}`;
|
||||
if (isRtl && !this.vertical) {
|
||||
this.style[gridTemplate] = `${secondary} var(--divider-width) ${primary}`;
|
||||
} else {
|
||||
this.style[gridTemplate] = `${primary} var(--divider-width) ${secondary}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Unset the alt grid template property
|
||||
|
|
|
|||
|
|
@ -51,6 +51,16 @@ export default css`
|
|||
right: 0;
|
||||
}
|
||||
|
||||
.tab-group--rtl .tab-group__scroll-button--start {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.tab-group--rtl .tab-group__scroll-button--end {
|
||||
left: 0;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
* Top
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ export default class SlTabGroup extends LitElement {
|
|||
// Move focus left or right
|
||||
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) {
|
||||
const activeEl = document.activeElement;
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
if (activeEl?.tagName.toLowerCase() === 'sl-tab') {
|
||||
let index = this.tabs.indexOf(activeEl as SlTab);
|
||||
|
|
@ -185,12 +186,12 @@ export default class SlTabGroup extends LitElement {
|
|||
} else if (event.key === 'End') {
|
||||
index = this.tabs.length - 1;
|
||||
} else if (
|
||||
(['top', 'bottom'].includes(this.placement) && event.key === 'ArrowLeft') ||
|
||||
(['top', 'bottom'].includes(this.placement) && event.key === (isRtl ? 'ArrowRight' : 'ArrowLeft')) ||
|
||||
(['start', 'end'].includes(this.placement) && event.key === 'ArrowUp')
|
||||
) {
|
||||
index--;
|
||||
} else if (
|
||||
(['top', 'bottom'].includes(this.placement) && event.key === 'ArrowRight') ||
|
||||
(['top', 'bottom'].includes(this.placement) && event.key === (isRtl ? 'ArrowLeft' : 'ArrowRight')) ||
|
||||
(['start', 'end'].includes(this.placement) && event.key === 'ArrowDown')
|
||||
) {
|
||||
index++;
|
||||
|
|
@ -221,14 +222,20 @@ export default class SlTabGroup extends LitElement {
|
|||
|
||||
handleScrollToStart() {
|
||||
this.nav.scroll({
|
||||
left: this.nav.scrollLeft - this.nav.clientWidth,
|
||||
left:
|
||||
this.localize.dir() === 'rtl'
|
||||
? this.nav.scrollLeft + this.nav.clientWidth
|
||||
: this.nav.scrollLeft - this.nav.clientWidth,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
|
||||
handleScrollToEnd() {
|
||||
this.nav.scroll({
|
||||
left: this.nav.scrollLeft + this.nav.clientWidth,
|
||||
left:
|
||||
this.localize.dir() === 'rtl'
|
||||
? this.nav.scrollLeft - this.nav.clientWidth
|
||||
: this.nav.scrollLeft + this.nav.clientWidth,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
|
|
@ -356,6 +363,8 @@ export default class SlTabGroup extends LitElement {
|
|||
}
|
||||
|
||||
render() {
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
return html`
|
||||
<div
|
||||
part="base"
|
||||
|
|
@ -378,7 +387,7 @@ export default class SlTabGroup extends LitElement {
|
|||
part="scroll-button scroll-button--start"
|
||||
exportparts="base:scroll-button__base"
|
||||
class="tab-group__scroll-button tab-group__scroll-button--start"
|
||||
name="chevron-left"
|
||||
name=${isRtl ? 'chevron-right' : 'chevron-left'}
|
||||
library="system"
|
||||
label=${this.localize.term('scrollToStart')}
|
||||
@click=${this.handleScrollToStart}
|
||||
|
|
@ -399,7 +408,7 @@ export default class SlTabGroup extends LitElement {
|
|||
part="scroll-button scroll-button--end"
|
||||
exportparts="base:scroll-button__base"
|
||||
class="tab-group__scroll-button tab-group__scroll-button--end"
|
||||
name="chevron-right"
|
||||
name=${isRtl ? 'chevron-left' : 'chevron-right'}
|
||||
library="system"
|
||||
label=${this.localize.term('scrollToEnd')}
|
||||
@click=${this.handleScrollToEnd}
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue