mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-24 23:01:57 +08:00
fix(range): implement RTL (from PR 17157) (#17384)
- MD PIN fixes not committed because they depend on mixin changes references #17012
This commit is contained in:

committed by
Brandy Carney

parent
d0a9fac5c7
commit
4f203bc230
@ -105,6 +105,11 @@
|
|||||||
@include border-radius(50%, 50%, 50%, 0);
|
@include border-radius(50%, 50%, 50%, 0);
|
||||||
@include margin-horizontal(-13px, null);
|
@include margin-horizontal(-13px, null);
|
||||||
|
|
||||||
|
@include rtl() {
|
||||||
|
/* stylelint-disable-next-line property-blacklist */
|
||||||
|
left: unset;
|
||||||
|
}
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
width: 26px;
|
width: 26px;
|
||||||
|
@ -79,6 +79,11 @@
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@include rtl() {
|
||||||
|
/* stylelint-disable-next-line property-blacklist */
|
||||||
|
left: unset;
|
||||||
|
}
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
width: var(--knob-handle-size);
|
width: var(--knob-handle-size);
|
||||||
@ -95,6 +100,12 @@
|
|||||||
.range-bar {
|
.range-bar {
|
||||||
@include border-radius(var(--bar-border-radius));
|
@include border-radius(var(--bar-border-radius));
|
||||||
@include position(calc((var(--height) - var(--bar-height)) / 2), null, null, 0);
|
@include position(calc((var(--height) - var(--bar-height)) / 2), null, null, 0);
|
||||||
|
|
||||||
|
@include rtl() {
|
||||||
|
/* stylelint-disable-next-line property-blacklist */
|
||||||
|
left: unset;
|
||||||
|
}
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -113,6 +124,11 @@
|
|||||||
calc(50% - var(--knob-size) / 2)
|
calc(50% - var(--knob-size) / 2)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@include rtl() {
|
||||||
|
/* stylelint-disable-next-line property-blacklist */
|
||||||
|
left: unset;
|
||||||
|
}
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
width: var(--knob-size);
|
width: var(--knob-size);
|
||||||
|
@ -235,7 +235,11 @@ export class Range implements ComponentInterface {
|
|||||||
const currentX = detail.currentX;
|
const currentX = detail.currentX;
|
||||||
|
|
||||||
// figure out which knob they started closer to
|
// figure out which knob they started closer to
|
||||||
const ratio = clamp(0, (currentX - rect.left) / rect.width, 1);
|
let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);
|
||||||
|
if (document.dir === 'rtl') {
|
||||||
|
ratio = 1 - ratio;
|
||||||
|
}
|
||||||
|
|
||||||
this.pressedKnob =
|
this.pressedKnob =
|
||||||
!this.dualKnobs ||
|
!this.dualKnobs ||
|
||||||
Math.abs(this.ratioA - ratio) < Math.abs(this.ratioB - ratio)
|
Math.abs(this.ratioA - ratio) < Math.abs(this.ratioB - ratio)
|
||||||
@ -262,6 +266,10 @@ export class Range implements ComponentInterface {
|
|||||||
// update the knob being interacted with
|
// update the knob being interacted with
|
||||||
const rect = this.rect;
|
const rect = this.rect;
|
||||||
let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);
|
let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);
|
||||||
|
if (document.dir === 'rtl') {
|
||||||
|
ratio = 1 - ratio;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.snaps) {
|
if (this.snaps) {
|
||||||
// snaps the ratio to the current value
|
// snaps the ratio to the current value
|
||||||
ratio = valueToRatio(
|
ratio = valueToRatio(
|
||||||
@ -353,31 +361,56 @@ export class Range implements ComponentInterface {
|
|||||||
render() {
|
render() {
|
||||||
const { min, max, step, ratioLower, ratioUpper } = this;
|
const { min, max, step, ratioLower, ratioUpper } = this;
|
||||||
|
|
||||||
const barL = `${ratioLower * 100}%`;
|
const barStart = `${ratioLower * 100}%`;
|
||||||
const barR = `${100 - ratioUpper * 100}%`;
|
const barEnd = `${100 - ratioUpper * 100}%`;
|
||||||
|
|
||||||
|
const isRTL = document.dir === 'rtl';
|
||||||
|
const start = isRTL ? 'right' : 'left';
|
||||||
|
const end = isRTL ? 'left' : 'right';
|
||||||
|
|
||||||
const ticks = [];
|
const ticks = [];
|
||||||
if (this.snaps) {
|
if (this.snaps) {
|
||||||
for (let value = min; value <= max; value += step) {
|
for (let value = min; value <= max; value += step) {
|
||||||
const ratio = valueToRatio(value, min, max);
|
const ratio = valueToRatio(value, min, max);
|
||||||
ticks.push({
|
|
||||||
|
const tick: any = {
|
||||||
ratio,
|
ratio,
|
||||||
active: ratio >= ratioLower && ratio <= ratioUpper,
|
active: ratio >= ratioLower && ratio <= ratioUpper,
|
||||||
left: `${ratio * 100}%`
|
};
|
||||||
});
|
|
||||||
|
tick[start] = `${ratio * 100}%`;
|
||||||
|
|
||||||
|
ticks.push(tick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tickStyle = (tick: any) => {
|
||||||
|
const style: any = {};
|
||||||
|
|
||||||
|
style[start] = tick[start];
|
||||||
|
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
|
||||||
|
const barStyle = () => {
|
||||||
|
const style: any = {};
|
||||||
|
|
||||||
|
style[start] = barStart;
|
||||||
|
style[end] = barEnd;
|
||||||
|
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
|
||||||
return [
|
return [
|
||||||
<slot name="start"></slot>,
|
<slot name="start"></slot>,
|
||||||
<div class="range-slider" ref={el => this.rangeSlider = el}>
|
<div class="range-slider" ref={el => this.rangeSlider = el}>
|
||||||
{ticks.map(t => (
|
{ticks.map(tick => (
|
||||||
<div
|
<div
|
||||||
style={{ left: t.left }}
|
style={tickStyle(tick)}
|
||||||
role="presentation"
|
role="presentation"
|
||||||
class={{
|
class={{
|
||||||
'range-tick': true,
|
'range-tick': true,
|
||||||
'range-tick-active': t.active
|
'range-tick-active': tick.active
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@ -386,10 +419,7 @@ export class Range implements ComponentInterface {
|
|||||||
<div
|
<div
|
||||||
class="range-bar range-bar-active"
|
class="range-bar range-bar-active"
|
||||||
role="presentation"
|
role="presentation"
|
||||||
style={{
|
style={barStyle()}
|
||||||
left: barL,
|
|
||||||
right: barR
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{ renderKnob({
|
{ renderKnob({
|
||||||
@ -435,6 +465,17 @@ interface RangeKnob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderKnob({ knob, value, ratio, min, max, disabled, pressed, pin, handleKeyboard }: RangeKnob) {
|
function renderKnob({ knob, value, ratio, min, max, disabled, pressed, pin, handleKeyboard }: RangeKnob) {
|
||||||
|
const isRTL = document.dir === 'rtl';
|
||||||
|
const start = isRTL ? 'right' : 'left';
|
||||||
|
|
||||||
|
const knobStyle = () => {
|
||||||
|
const style: any = {};
|
||||||
|
|
||||||
|
style[start] = `${ratio * 100}%`;
|
||||||
|
|
||||||
|
return style;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onKeyDown={(ev: KeyboardEvent) => {
|
onKeyDown={(ev: KeyboardEvent) => {
|
||||||
@ -458,9 +499,7 @@ function renderKnob({ knob, value, ratio, min, max, disabled, pressed, pin, hand
|
|||||||
'range-knob-min': value === min,
|
'range-knob-min': value === min,
|
||||||
'range-knob-max': value === max
|
'range-knob-max': value === max
|
||||||
}}
|
}}
|
||||||
style={{
|
style={knobStyle()}
|
||||||
'left': `${ratio * 100}%`
|
|
||||||
}}
|
|
||||||
role="slider"
|
role="slider"
|
||||||
tabindex={disabled ? -1 : 0}
|
tabindex={disabled ? -1 : 0}
|
||||||
aria-valuemin={min}
|
aria-valuemin={min}
|
||||||
|
Reference in New Issue
Block a user