Skip to content

Commit 4f203bc

Browse files
abennounabrandyscarney
authored andcommitted
fix(range): implement RTL (from PR 17157) (#17384)
- MD PIN fixes not committed because they depend on mixin changes references #17012
1 parent d0a9fac commit 4f203bc

File tree

3 files changed

+76
-16
lines changed

3 files changed

+76
-16
lines changed

core/src/components/range/range.md.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@
105105
@include border-radius(50%, 50%, 50%, 0);
106106
@include margin-horizontal(-13px, null);
107107

108+
@include rtl() {
109+
/* stylelint-disable-next-line property-blacklist */
110+
left: unset;
111+
}
112+
108113
position: absolute;
109114

110115
width: 26px;

core/src/components/range/range.scss

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@
7979
null
8080
);
8181

82+
@include rtl() {
83+
/* stylelint-disable-next-line property-blacklist */
84+
left: unset;
85+
}
86+
8287
position: absolute;
8388

8489
width: var(--knob-handle-size);
@@ -95,6 +100,12 @@
95100
.range-bar {
96101
@include border-radius(var(--bar-border-radius));
97102
@include position(calc((var(--height) - var(--bar-height)) / 2), null, null, 0);
103+
104+
@include rtl() {
105+
/* stylelint-disable-next-line property-blacklist */
106+
left: unset;
107+
}
108+
98109
position: absolute;
99110

100111
width: 100%;
@@ -113,6 +124,11 @@
113124
calc(50% - var(--knob-size) / 2)
114125
);
115126

127+
@include rtl() {
128+
/* stylelint-disable-next-line property-blacklist */
129+
left: unset;
130+
}
131+
116132
position: absolute;
117133

118134
width: var(--knob-size);

core/src/components/range/range.tsx

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,11 @@ export class Range implements ComponentInterface {
235235
const currentX = detail.currentX;
236236

237237
// figure out which knob they started closer to
238-
const ratio = clamp(0, (currentX - rect.left) / rect.width, 1);
238+
let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);
239+
if (document.dir === 'rtl') {
240+
ratio = 1 - ratio;
241+
}
242+
239243
this.pressedKnob =
240244
!this.dualKnobs ||
241245
Math.abs(this.ratioA - ratio) < Math.abs(this.ratioB - ratio)
@@ -262,6 +266,10 @@ export class Range implements ComponentInterface {
262266
// update the knob being interacted with
263267
const rect = this.rect;
264268
let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);
269+
if (document.dir === 'rtl') {
270+
ratio = 1 - ratio;
271+
}
272+
265273
if (this.snaps) {
266274
// snaps the ratio to the current value
267275
ratio = valueToRatio(
@@ -353,31 +361,56 @@ export class Range implements ComponentInterface {
353361
render() {
354362
const { min, max, step, ratioLower, ratioUpper } = this;
355363

356-
const barL = `${ratioLower * 100}%`;
357-
const barR = `${100 - ratioUpper * 100}%`;
364+
const barStart = `${ratioLower * 100}%`;
365+
const barEnd = `${100 - ratioUpper * 100}%`;
366+
367+
const isRTL = document.dir === 'rtl';
368+
const start = isRTL ? 'right' : 'left';
369+
const end = isRTL ? 'left' : 'right';
358370

359371
const ticks = [];
360372
if (this.snaps) {
361373
for (let value = min; value <= max; value += step) {
362374
const ratio = valueToRatio(value, min, max);
363-
ticks.push({
375+
376+
const tick: any = {
364377
ratio,
365378
active: ratio >= ratioLower && ratio <= ratioUpper,
366-
left: `${ratio * 100}%`
367-
});
379+
};
380+
381+
tick[start] = `${ratio * 100}%`;
382+
383+
ticks.push(tick);
368384
}
369385
}
370386

387+
const tickStyle = (tick: any) => {
388+
const style: any = {};
389+
390+
style[start] = tick[start];
391+
392+
return style;
393+
};
394+
395+
const barStyle = () => {
396+
const style: any = {};
397+
398+
style[start] = barStart;
399+
style[end] = barEnd;
400+
401+
return style;
402+
};
403+
371404
return [
372405
<slot name="start"></slot>,
373406
<div class="range-slider" ref={el => this.rangeSlider = el}>
374-
{ticks.map(t => (
407+
{ticks.map(tick => (
375408
<div
376-
style={{ left: t.left }}
409+
style={tickStyle(tick)}
377410
role="presentation"
378411
class={{
379412
'range-tick': true,
380-
'range-tick-active': t.active
413+
'range-tick-active': tick.active
381414
}}
382415
/>
383416
))}
@@ -386,10 +419,7 @@ export class Range implements ComponentInterface {
386419
<div
387420
class="range-bar range-bar-active"
388421
role="presentation"
389-
style={{
390-
left: barL,
391-
right: barR
392-
}}
422+
style={barStyle()}
393423
/>
394424

395425
{ renderKnob({
@@ -435,6 +465,17 @@ interface RangeKnob {
435465
}
436466

437467
function renderKnob({ knob, value, ratio, min, max, disabled, pressed, pin, handleKeyboard }: RangeKnob) {
468+
const isRTL = document.dir === 'rtl';
469+
const start = isRTL ? 'right' : 'left';
470+
471+
const knobStyle = () => {
472+
const style: any = {};
473+
474+
style[start] = `${ratio * 100}%`;
475+
476+
return style;
477+
};
478+
438479
return (
439480
<div
440481
onKeyDown={(ev: KeyboardEvent) => {
@@ -458,9 +499,7 @@ function renderKnob({ knob, value, ratio, min, max, disabled, pressed, pin, hand
458499
'range-knob-min': value === min,
459500
'range-knob-max': value === max
460501
}}
461-
style={{
462-
'left': `${ratio * 100}%`
463-
}}
502+
style={knobStyle()}
464503
role="slider"
465504
tabindex={disabled ? -1 : 0}
466505
aria-valuemin={min}

0 commit comments

Comments
 (0)