fix RTL in breadcrumb, tab group, and split panel

pull/792/head
Cory LaViska 2022-06-08 17:15:40 -04:00
rodzic 4c3313e275
commit d0ff2fef35
4 zmienionych plików z 62 dodań i 9 usunięć

Wyświetl plik

@ -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>
`;
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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
*/

Wyświetl plik

@ -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}