Skip to content

Commit

Permalink
fix: support RTL direction (#213)
Browse files Browse the repository at this point in the history
* fix: support RTL direction

fixes #212

* fix: fix for old Safari

* fix: remove test page rtl
  • Loading branch information
nolanlawson committed Aug 14, 2021
1 parent 468fd80 commit 7875925
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 26 deletions.
9 changes: 5 additions & 4 deletions src/picker/components/Picker/Picker.html
Expand Up @@ -77,7 +77,7 @@
</div>
<div class="nav"
role="tablist"
style="grid-template-columns: repeat({groups.length}, 1fr);"
style="grid-template-columns: repeat({groups.length}, 1fr)"
aria-label={i18n.categoriesLabel}
on:keydown={onNavKeydown}>
{#each groups as group (group.id)}
Expand All @@ -95,7 +95,8 @@
{/each}
</div>
<div class="indicator-wrapper">
<div class="indicator" style={indicatorStyle}>
<div class="indicator"
style="transform: translateX({(isRtl ? -1 : 1) * currentGroupIndex * 100}%)">
</div>
</div>

Expand All @@ -114,7 +115,7 @@
on:click={onEmojiClick}
bind:this={tabpanelElement}
>
<div use:calculateEmojiGridWidth>
<div use:calculateEmojiGridStyle>
{#each currentEmojisWithCategories as emojiWithCategory, i (emojiWithCategory.category)}
<div
id="menu-label-{i}"
Expand Down Expand Up @@ -161,7 +162,7 @@
<div class="favorites emoji-menu {message ? 'gone': ''}"
role="menu"
aria-label={i18n.favoritesLabel}
style="padding-right: {scrollbarWidth}px;"
style="padding-inline-end: {scrollbarWidth}px"
on:click={onEmojiClick}
data-testid="favorites">
<!-- The reason the emoji logic below is largely duplicated is because it turns out we get a smaller
Expand Down
40 changes: 21 additions & 19 deletions src/picker/components/Picker/Picker.js
Expand Up @@ -42,7 +42,6 @@ let tabpanelElement
let searchMode = false // eslint-disable-line no-unused-vars
let activeSearchItem = -1
let message // eslint-disable-line no-unused-vars
let indicatorStyle = '' // eslint-disable-line no-unused-vars
let skinTonePickerExpanded = false
let skinTonePickerExpandedAfterAnimation = false // eslint-disable-line no-unused-vars
let skinToneDropdown
Expand All @@ -55,6 +54,7 @@ let skinTones = []
let currentFavorites = [] // eslint-disable-line no-unused-vars
let defaultFavoriteEmojis
let numColumns = DEFAULT_NUM_COLUMNS
let isRtl = false
let scrollbarWidth = 0 // eslint-disable-line no-unused-vars
let currentGroupIndex = 0
let groups = defaultGroups
Expand Down Expand Up @@ -221,22 +221,31 @@ $: {
// 1) Re-calculate the --num-columns var because it may have changed
// 2) Re-calculate the scrollbar width because it may have changed
// (i.e. because the number of items changed)
// 3) Re-calculate whether we're in RTL mode or not.
//
// The benefit of doing this in one place is to align with rAF/ResizeObserver
// and do all the calculations in one go. RTL vs LTR is not strictly width-related,
// but since we're already reading the style here, and since it's already aligned with
// the rAF loop, this is the most appropriate place to do it perf-wise.
//

// eslint-disable-next-line no-unused-vars
function calculateEmojiGridWidth (node) {
function calculateEmojiGridStyle (node) {
return widthCalculator.calculateWidth(node, width => {
/* istanbul ignore next */
const newNumColumns = process.env.NODE_ENV === 'test'
? DEFAULT_NUM_COLUMNS
: parseInt(getComputedStyle(rootElement).getPropertyValue('--num-columns'), 10)
/* istanbul ignore next */
const parentWidth = process.env.NODE_ENV === 'test' // jsdom throws an error here occasionally
? 1
: node.parentElement.getBoundingClientRect().width
const newScrollbarWidth = parentWidth - width
numColumns = newNumColumns
scrollbarWidth = newScrollbarWidth // eslint-disable-line no-unused-vars
if (process.env.NODE_ENV !== 'test') { // jsdom throws errors for this kind of fancy stuff
// read all the style/layout calculations we need to make
const style = getComputedStyle(rootElement)
const newNumColumns = parseInt(style.getPropertyValue('--num-columns'), 10)
const newIsRtl = style.getPropertyValue('direction') === 'rtl'
const parentWidth = node.parentElement.getBoundingClientRect().width
const newScrollbarWidth = parentWidth - width

// write to Svelte variables
numColumns = newNumColumns
scrollbarWidth = newScrollbarWidth // eslint-disable-line no-unused-vars
isRtl = newIsRtl // eslint-disable-line no-unused-vars
}
})
}

Expand All @@ -246,13 +255,6 @@ function calculateEmojiGridWidth (node) {

$: currentGroup = groups[currentGroupIndex]

//
// Animate the indicator (little blue bar below category icons)
//

// eslint-disable-next-line no-unused-vars
$: indicatorStyle = `transform: translateX(${`${currentGroupIndex * 100}%`})`

//
// Set or update the currentEmojis. Check for invalid ZWJ renderings
// (i.e. double emoji).
Expand Down
11 changes: 8 additions & 3 deletions src/picker/styles/picker.scss
Expand Up @@ -21,7 +21,7 @@ $skintoneZIndex3: 3;

.skintone-list {
position: absolute;
right: 0;
inset-inline-end: 0;
top: 0;
z-index: $skintoneZIndex2;
overflow: visible;
Expand All @@ -41,6 +41,12 @@ $skintoneZIndex3: 3;
transition-duration: 0.001s;
}

// TODO: remove this when old iOS Safari drops out of usage: https://caniuse.com/css-logical-props
// For now, we don't support RTL in old versions of iOS
@supports not (inset-inline-end: 0) {
right: 0;
}

&.no-animate {
transition: none;
}
Expand Down Expand Up @@ -175,12 +181,11 @@ button.emoji,
background: var(--background);
}


.search-row {
display: flex;
align-items: center;
position: relative;
padding-left: var(--emoji-padding);
padding-inline-start: var(--emoji-padding);
padding-bottom: var(--emoji-padding);
}

Expand Down
2 changes: 2 additions & 0 deletions test/adhoc/index.html
Expand Up @@ -18,6 +18,8 @@
@media screen and (max-width: 320px) {
emoji-picker {
width: 100%;
--num-columns: 6;
--category-emoji-size: 1.125rem;
}
}
@media screen and (max-width: 240px) {
Expand Down

0 comments on commit 7875925

Please sign in to comment.