kopia lustrzana https://github.com/shoelace-style/shoelace
more resilient directionality checks; fixes #2188
rodzic
761e06220a
commit
e91dc034d0
|
@ -15,6 +15,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti
|
|||
## Next
|
||||
|
||||
- Fixed a bug in `<sl-relative-time>` where the title attribute would show with redundant info [#2184]
|
||||
- Updated all checks for directionality to use `this.localize.dir()` instead of `el.matches(:dir(rtl))` so older browsers don't error out [#2188]
|
||||
|
||||
## 2.17.1
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ export default class SlCarousel extends ShoelaceElement {
|
|||
private handleKeyDown(event: KeyboardEvent) {
|
||||
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) {
|
||||
const target = event.target as HTMLElement;
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
const isFocusInPagination = target.closest('[part~="pagination-item"]') !== null;
|
||||
const isNext =
|
||||
event.key === 'ArrowDown' || (!isRtl && event.key === 'ArrowRight') || (isRtl && event.key === 'ArrowLeft');
|
||||
|
@ -461,7 +461,7 @@ export default class SlCarousel extends ShoelaceElement {
|
|||
: clamp(index, 0, slides.length - slidesPerPage);
|
||||
this.activeSlide = newActiveSlide;
|
||||
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
// Get the index of the next slide. For looping carousel it adds `slidesPerPage`
|
||||
// to normalize the starting index in order to ignore the first nth clones.
|
||||
|
|
|
@ -187,7 +187,7 @@ export default class SlDetails extends ShoelaceElement {
|
|||
}
|
||||
|
||||
render() {
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
return html`
|
||||
<details
|
||||
|
|
|
@ -2,6 +2,7 @@ import { clamp } from '../../internal/math.js';
|
|||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { drag } from '../../internal/drag.js';
|
||||
import { html } from 'lit';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
|
@ -38,6 +39,8 @@ export default class SlImageComparer extends ShoelaceElement {
|
|||
static styles: CSSResultGroup = [componentStyles, styles];
|
||||
static scopedElement = { 'sl-icon': SlIcon };
|
||||
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
@query('.image-comparer') base: HTMLElement;
|
||||
@query('.image-comparer__handle') handle: HTMLElement;
|
||||
|
||||
|
@ -46,7 +49,7 @@ export default class SlImageComparer extends ShoelaceElement {
|
|||
|
||||
private handleDrag(event: PointerEvent) {
|
||||
const { width } = this.base.getBoundingClientRect();
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
|
@ -60,8 +63,8 @@ export default class SlImageComparer extends ShoelaceElement {
|
|||
}
|
||||
|
||||
private handleKeyDown(event: KeyboardEvent) {
|
||||
const isLtr = this.matches(':dir(ltr)');
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isLtr = this.localize.dir() === 'ltr';
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
if (['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) {
|
||||
const incr = event.shiftKey ? 10 : 1;
|
||||
|
@ -93,7 +96,7 @@ export default class SlImageComparer extends ShoelaceElement {
|
|||
}
|
||||
|
||||
render() {
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
return html`
|
||||
<div
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { getTextContent, HasSlotController } from '../../internal/slot.js';
|
||||
import { html } from 'lit';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
import { SubmenuController } from './submenu-controller.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
|
@ -47,6 +48,7 @@ export default class SlMenuItem extends ShoelaceElement {
|
|||
};
|
||||
|
||||
private cachedTextLabel: string;
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
|
||||
@query('.menu-item') menuItem: HTMLElement;
|
||||
|
@ -153,7 +155,7 @@ export default class SlMenuItem extends ShoelaceElement {
|
|||
}
|
||||
|
||||
render() {
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
const isSubmenuExpanded = this.submenuController.isExpanded();
|
||||
|
||||
return html`
|
||||
|
|
|
@ -195,7 +195,7 @@ export class SubmenuController implements ReactiveController {
|
|||
private handlePopupReposition = () => {
|
||||
const submenuSlot: HTMLSlotElement | null = this.host.renderRoot.querySelector("slot[name='submenu']");
|
||||
const menu = submenuSlot?.assignedElements({ flatten: true }).filter(el => el.localName === 'sl-menu')[0];
|
||||
const isRtl = this.host.matches(':dir(rtl)');
|
||||
const isRtl = getComputedStyle(this.host).direction === 'rtl';
|
||||
if (!menu) {
|
||||
return;
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ export class SubmenuController implements ReactiveController {
|
|||
}
|
||||
|
||||
renderSubmenu() {
|
||||
const isRtl = this.host.matches(':dir(rtl)');
|
||||
const isRtl = getComputedStyle(this.host).direction === 'rtl';
|
||||
|
||||
// Always render the slot, but conditionally render the outer <sl-popup>
|
||||
if (!this.isConnected) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { arrow, autoUpdate, computePosition, flip, offset, platform, shift, size } from '@floating-ui/dom';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { html } from 'lit';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import { offsetParent } from 'composed-offset-position';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
|
@ -56,6 +57,7 @@ export default class SlPopup extends ShoelaceElement {
|
|||
|
||||
private anchorEl: Element | VirtualElement | null;
|
||||
private cleanup: ReturnType<typeof autoUpdate> | undefined;
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
/** A reference to the internal popup container. Useful for animating and styling the popup with JavaScript. */
|
||||
@query('.popup') popup: HTMLElement;
|
||||
|
@ -413,7 +415,7 @@ export default class SlPopup extends ShoelaceElement {
|
|||
//
|
||||
// Source: https://github.com/floating-ui/floating-ui/blob/cb3b6ab07f95275730d3e6e46c702f8d4908b55c/packages/dom/src/utils/getDocumentRect.ts#L31
|
||||
//
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
const staticSide = { top: 'bottom', right: 'left', bottom: 'top', left: 'right' }[placement.split('-')[0]]!;
|
||||
|
||||
this.setAttribute('data-current-placement', placement);
|
||||
|
|
|
@ -175,7 +175,7 @@ export default class SlRange extends ShoelaceElement implements ShoelaceFormCont
|
|||
const inputWidth = this.input.offsetWidth;
|
||||
const tooltipWidth = this.output.offsetWidth;
|
||||
const thumbSize = getComputedStyle(this.input).getPropertyValue('--thumb-size');
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
const percentAsWidth = inputWidth * percent;
|
||||
|
||||
// The calculations are used to "guess" where the thumb is located. Since we're using the native range control
|
||||
|
|
|
@ -2,6 +2,7 @@ import { clamp } from '../../internal/math.js';
|
|||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { eventOptions, property, query, state } from 'lit/decorators.js';
|
||||
import { html } from 'lit';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
|
@ -35,6 +36,8 @@ export default class SlRating extends ShoelaceElement {
|
|||
static styles: CSSResultGroup = [componentStyles, styles];
|
||||
static dependencies = { 'sl-icon': SlIcon };
|
||||
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
@query('.rating') rating: HTMLElement;
|
||||
|
||||
@state() private hoverValue = 0;
|
||||
|
@ -77,7 +80,7 @@ export default class SlRating extends ShoelaceElement {
|
|||
}
|
||||
|
||||
private getValueFromXCoordinate(coordinate: number) {
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
const { left, right, width } = this.rating.getBoundingClientRect();
|
||||
const value = isRtl
|
||||
? this.roundToPrecision(((right - coordinate) / width) * this.max, this.precision)
|
||||
|
@ -105,8 +108,8 @@ export default class SlRating extends ShoelaceElement {
|
|||
}
|
||||
|
||||
private handleKeyDown(event: KeyboardEvent) {
|
||||
const isLtr = this.matches(':dir(ltr)');
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isLtr = this.localize.dir() === 'ltr';
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
const oldValue = this.value;
|
||||
|
||||
if (this.disabled || this.readonly) {
|
||||
|
@ -211,7 +214,7 @@ export default class SlRating extends ShoelaceElement {
|
|||
}
|
||||
|
||||
render() {
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
const counter = Array.from(Array(this.max).keys());
|
||||
let displayValue = 0;
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ export default class SlSplitPanel extends ShoelaceElement {
|
|||
}
|
||||
|
||||
private handleDrag(event: PointerEvent) {
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
if (this.disabled) {
|
||||
return;
|
||||
|
@ -223,7 +223,7 @@ export default class SlSplitPanel extends ShoelaceElement {
|
|||
render() {
|
||||
const gridTemplate = this.vertical ? 'gridTemplateRows' : 'gridTemplateColumns';
|
||||
const gridTemplateAlt = this.vertical ? 'gridTemplateColumns' : 'gridTemplateRows';
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
const primary = `
|
||||
clamp(
|
||||
0%,
|
||||
|
|
|
@ -46,14 +46,13 @@ export default class SlTabGroup extends ShoelaceElement {
|
|||
static styles: CSSResultGroup = [componentStyles, styles];
|
||||
static dependencies = { 'sl-icon-button': SlIconButton, 'sl-resize-observer': SlResizeObserver };
|
||||
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
private activeTab?: SlTab;
|
||||
private mutationObserver: MutationObserver;
|
||||
private resizeObserver: ResizeObserver;
|
||||
private tabs: SlTab[] = [];
|
||||
private focusableTabs: SlTab[] = [];
|
||||
private panels: SlTabPanel[] = [];
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
@query('.tab-group') tabGroup: HTMLElement;
|
||||
@query('.tab-group__body') body: HTMLSlotElement;
|
||||
|
@ -182,7 +181,7 @@ export default class SlTabGroup extends ShoelaceElement {
|
|||
// Move focus left or right
|
||||
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) {
|
||||
const activeEl = this.tabs.find(t => t.matches(':focus'));
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
let nextTab: null | SlTab = null;
|
||||
|
||||
if (activeEl?.tagName.toLowerCase() === 'sl-tab') {
|
||||
|
@ -302,7 +301,7 @@ export default class SlTabGroup extends ShoelaceElement {
|
|||
|
||||
const width = currentTab.clientWidth;
|
||||
const height = currentTab.clientHeight;
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
// We can't used offsetLeft/offsetTop here due to a shadow parent issue where neither can getBoundingClientRect
|
||||
// because it provides invalid values for animating elements: https://bugs.chromium.org/p/chromium/issues/detail?id=920069
|
||||
|
@ -434,7 +433,7 @@ export default class SlTabGroup extends ShoelaceElement {
|
|||
}
|
||||
|
||||
render() {
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
return html`
|
||||
<div
|
||||
|
|
|
@ -223,7 +223,7 @@ export default class SlTreeItem extends ShoelaceElement {
|
|||
}
|
||||
|
||||
render() {
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
const showExpandButton = !this.loading && (!this.isLeaf || this.lazy);
|
||||
|
||||
return html`
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { clamp } from '../../internal/math.js';
|
||||
import { html } from 'lit';
|
||||
import { LocalizeController } from '../../utilities/localize.js';
|
||||
import { property, query } from 'lit/decorators.js';
|
||||
import { watch } from '../../internal/watch.js';
|
||||
import componentStyles from '../../styles/component.styles.js';
|
||||
|
@ -89,6 +90,7 @@ export default class SlTree extends ShoelaceElement {
|
|||
private lastFocusedItem: SlTreeItem | null;
|
||||
private mutationObserver: MutationObserver;
|
||||
private clickTarget: SlTreeItem | null = null;
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
@ -222,8 +224,8 @@ export default class SlTree extends ShoelaceElement {
|
|||
}
|
||||
|
||||
const items = this.getFocusableItems();
|
||||
const isLtr = this.matches(':dir(ltr)');
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
const isLtr = this.localize.dir() === 'ltr';
|
||||
const isRtl = this.localize.dir() === 'rtl';
|
||||
|
||||
if (items.length > 0) {
|
||||
event.preventDefault();
|
||||
|
|
Ładowanie…
Reference in New Issue