From 346f13e5a53b262a8ef5bc54382be034712e3c39 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Fri, 2 Sep 2022 11:28:49 -0400 Subject: [PATCH] fix arrow placement --- docs/resources/changelog.md | 1 + src/components/popup/popup.ts | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/resources/changelog.md b/docs/resources/changelog.md index 7aa42767b..ace54e475 100644 --- a/docs/resources/changelog.md +++ b/docs/resources/changelog.md @@ -16,6 +16,7 @@ This release removes the `` component. When this component - Added an expand/collapse animation to `` - Added `sl-lazy-change` event to `` - Fixed a bug in `` that didn't account for the arrow's diagonal size +- Fixed a bug in `` that caused arrow placement to be incorrect with RTL - Fixed a bug in `` that prevented custom expand/collapse icons from rendering - Fixed a bug in `` where the `expand-icon` and `collapse-icon` slots were reversed - Fixed a bug in `` that prevented the keyboard from working after lazy loading [#882](https://github.com/shoelace-style/shoelace/issues/882) diff --git a/src/components/popup/popup.ts b/src/components/popup/popup.ts index d0f030460..3aa9381a9 100644 --- a/src/components/popup/popup.ts +++ b/src/components/popup/popup.ts @@ -369,6 +369,13 @@ export default class SlPopup extends ShoelaceElement { middleware, strategy: this.strategy }).then(({ x, y, middlewareData, placement }) => { + // + // Even though we have our own localization utility, it uses different heuristics to determine RTL. Because of + // that, we'll use the same approach that Floating UI uses. + // + // Source: https://github.com/floating-ui/floating-ui/blob/cb3b6ab07f95275730d3e6e46c702f8d4908b55c/packages/dom/src/utils/getDocumentRect.ts#L31 + // + const isRtl = getComputedStyle(this).direction === 'rtl'; const staticSide = { top: 'bottom', right: 'left', bottom: 'top', left: 'right' }[placement.split('-')[0]]!; this.setAttribute('data-current-placement', placement); @@ -388,11 +395,15 @@ export default class SlPopup extends ShoelaceElement { if (this.arrowPlacement === 'start') { // Start - left = typeof arrowX === 'number' ? `calc(${this.arrowPadding}px - var(--arrow-padding-offset))` : ''; + const value = typeof arrowX === 'number' ? `calc(${this.arrowPadding}px - var(--arrow-padding-offset))` : ''; top = typeof arrowY === 'number' ? `calc(${this.arrowPadding}px - var(--arrow-padding-offset))` : ''; + right = isRtl ? value : ''; + left = isRtl ? '' : value; } else if (this.arrowPlacement === 'end') { // End - right = typeof arrowX === 'number' ? `calc(${this.arrowPadding}px - var(--arrow-padding-offset))` : ''; + const value = typeof arrowX === 'number' ? `calc(${this.arrowPadding}px - var(--arrow-padding-offset))` : ''; + right = isRtl ? '' : value; + left = isRtl ? value : ''; bottom = typeof arrowY === 'number' ? `calc(${this.arrowPadding}px - var(--arrow-padding-offset))` : ''; } else if (this.arrowPlacement === 'center') { // Center