mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge pull request #3743 from hadicharara/hadicharara/added-support-for-rtl-layouts
Add Initial support for RTL layouts
This commit is contained in:
commit
84c007fa0b
82 changed files with 1163 additions and 242 deletions
|
@ -17,20 +17,36 @@
|
|||
align-items: center;
|
||||
text-transform: none;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
border-width: 0 0 0.1em 0;
|
||||
border-style: solid;
|
||||
padding-left: 0.1em;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
|
||||
[dir="ltr"] & {
|
||||
text-align: left;
|
||||
padding-left: 0.1em;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
text-align: right;
|
||||
padding-right: 0.1em;
|
||||
}
|
||||
}
|
||||
|
||||
.emby-collapse-expandIcon {
|
||||
transform-origin: 50% 50%;
|
||||
transition: transform 180ms ease-out;
|
||||
position: absolute;
|
||||
right: 0.5em;
|
||||
font-size: 1.5em;
|
||||
|
||||
[dir="ltr"] & {
|
||||
right: 0.5em;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
left: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.emby-collapse-expandIconExpanded {
|
||||
|
|
|
@ -45,13 +45,17 @@
|
|||
margin: 0 0.5em 1.8em;
|
||||
}
|
||||
|
||||
.inlineForm .inputContainer:first-child,
|
||||
.inlineForm .selectContainer:first-child {
|
||||
[dir="rtl"] .inlineForm .inputContainer:last-child,
|
||||
[dir="rtl"] .inlineForm .selectContainer:last-child,
|
||||
[dir="ltr"] .inlineForm .inputContainer:first-child,
|
||||
[dir="ltr"] .inlineForm .selectContainer:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.inlineForm .inputContainer:last-child,
|
||||
.inlineForm .selectContainer:last-child {
|
||||
[dir="ltr"] .inlineForm .inputContainer:last-child,
|
||||
[dir="ltr"] .inlineForm .selectContainer:last-child,
|
||||
[dir="rtl"] .inlineForm .inputContainer:first-child,
|
||||
[dir="rtl"] .inlineForm .selectContainer:first-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import './emby-progressring.scss';
|
||||
import 'webcomponents.js/webcomponents-lite';
|
||||
import template from './emby-progressring.template.html';
|
||||
import { getCurrentDateTimeLocale } from '../../scripts/globalize';
|
||||
|
||||
/* eslint-disable indent */
|
||||
|
||||
|
@ -8,6 +9,7 @@ import template from './emby-progressring.template.html';
|
|||
|
||||
EmbyProgressRing.createdCallback = function () {
|
||||
this.classList.add('progressring');
|
||||
this.setAttribute('dir', 'ltr');
|
||||
const instance = this;
|
||||
|
||||
instance.innerHTML = template;
|
||||
|
@ -70,7 +72,10 @@ import template from './emby-progressring.template.html';
|
|||
this.querySelector('.animate-75-100-b').style.transform = 'rotate(' + angle + 'deg)';
|
||||
}
|
||||
|
||||
this.querySelector('.progressring-text').innerHTML = progress + '%';
|
||||
this.querySelector('.progressring-text').innerHTML = new Intl.NumberFormat(getCurrentDateTimeLocale(), {
|
||||
style: 'percent',
|
||||
maximumFractionDigits: 0
|
||||
}).format(progress / 100);
|
||||
};
|
||||
|
||||
EmbyProgressRing.attachedCallback = function () {
|
||||
|
|
|
@ -32,11 +32,18 @@
|
|||
|
||||
.mdl-radio__circles {
|
||||
position: relative;
|
||||
margin-right: 0.54em;
|
||||
width: 1.08em;
|
||||
height: 1.08em;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
|
||||
[dir="ltr"] & {
|
||||
margin-right: 0.54em;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
margin-left: 0.54em;
|
||||
}
|
||||
}
|
||||
|
||||
.mdl-radio__circles svg {
|
||||
|
@ -44,9 +51,16 @@
|
|||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
overflow: visible;
|
||||
|
||||
[dir="ltr"] & {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mdl-radio__button:disabled + .mdl-radio__circles {
|
||||
|
|
|
@ -40,6 +40,11 @@ const EmbyScrollButtonsPrototype = Object.create(HTMLDivElement.prototype);
|
|||
}
|
||||
|
||||
function updateScrollButtons(scrollButtons, scrollSize, scrollPos, scrollWidth) {
|
||||
let localeAwarePos = scrollPos;
|
||||
if (globalize.getIsElementRTL(scrollButtons)) {
|
||||
localeAwarePos *= -1;
|
||||
}
|
||||
|
||||
// TODO: Check if hack is really needed
|
||||
// hack alert add twenty for rounding errors
|
||||
if (scrollWidth <= scrollSize + 20) {
|
||||
|
@ -50,13 +55,13 @@ const EmbyScrollButtonsPrototype = Object.create(HTMLDivElement.prototype);
|
|||
scrollButtons.scrollButtonsRight.classList.remove('hide');
|
||||
}
|
||||
|
||||
if (scrollPos > 0) {
|
||||
if (localeAwarePos > 0) {
|
||||
scrollButtons.scrollButtonsLeft.disabled = false;
|
||||
} else {
|
||||
scrollButtons.scrollButtonsLeft.disabled = true;
|
||||
}
|
||||
|
||||
const scrollPosEnd = scrollPos + scrollSize;
|
||||
const scrollPosEnd = localeAwarePos + scrollSize;
|
||||
if (scrollWidth > 0 && scrollPosEnd >= scrollWidth) {
|
||||
scrollButtons.scrollButtonsRight.disabled = true;
|
||||
} else {
|
||||
|
@ -138,6 +143,12 @@ const EmbyScrollButtonsPrototype = Object.create(HTMLDivElement.prototype);
|
|||
newPos = scrollPos + scrollSize;
|
||||
}
|
||||
|
||||
if (globalize.getIsRTL() && direction === 'left') {
|
||||
newPos = scrollPos + scrollSize;
|
||||
} else if (globalize.getIsRTL()) {
|
||||
newPos = Math.min(0, scrollPos - scrollSize);
|
||||
}
|
||||
|
||||
scroller.scrollToPosition(newPos, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
.emby-scrollbuttons {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 104px;
|
||||
|
@ -10,6 +9,14 @@
|
|||
z-index: 1;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
|
||||
[dir="ltr"] & {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.emby-scrollbuttons-button > .material-icons {
|
||||
|
|
|
@ -9,17 +9,24 @@
|
|||
margin-right: max(env(safe-area-inset-right), 3.3%);
|
||||
}
|
||||
|
||||
/* align first card in scroller to heading */
|
||||
.itemsContainer > .card > .cardBox {
|
||||
margin-left: 0;
|
||||
margin-right: 1.2em;
|
||||
}
|
||||
|
||||
.servers > .card > .cardBox {
|
||||
margin-left: 0.6em;
|
||||
margin-right: 0.6em;
|
||||
}
|
||||
|
||||
/* align first card in scroller to heading */
|
||||
.itemsContainer > .card > .cardBox {
|
||||
[dir="ltr"] & {
|
||||
margin-left: 0;
|
||||
margin-right: 1.2em;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
margin-right: 0;
|
||||
margin-left: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.layout-tv .emby-scroller,
|
||||
.layout-mobile .emby-scroller {
|
||||
padding-left: 3.3%;
|
||||
|
|
|
@ -11,13 +11,20 @@
|
|||
/* General select styles: change as needed */
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
padding: 0.5em 1.9em 0.5em 0.5em;
|
||||
|
||||
/* Prevent padding from causing width overflow */
|
||||
box-sizing: border-box;
|
||||
outline: none !important;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
width: 100%;
|
||||
|
||||
[dir="ltr"] & {
|
||||
padding: 0.5em 1.9em 0.5em 0.5em;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
padding: 0.5em 0.5em 0.5em 1.9em;
|
||||
}
|
||||
}
|
||||
|
||||
.emby-select[disabled] {
|
||||
|
@ -34,8 +41,15 @@
|
|||
}
|
||||
|
||||
.selectContainer-inline > .emby-select {
|
||||
padding: 0.3em 1.9em 0.3em 0.5em;
|
||||
font-size: inherit;
|
||||
|
||||
[dir="ltr"] & {
|
||||
padding: 0.3em 1.9em 0.3em 0.5em;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
padding: 0.3em 0.5em 0.3em 1.9em;
|
||||
}
|
||||
}
|
||||
|
||||
.selectContainer-inline > .emby-select[disabled] {
|
||||
|
@ -92,10 +106,17 @@
|
|||
|
||||
.selectArrowContainer {
|
||||
position: absolute;
|
||||
right: 0.3em;
|
||||
top: 0.2em;
|
||||
color: inherit;
|
||||
pointer-events: none;
|
||||
|
||||
[dir="ltr"] & {
|
||||
right: 0.3em;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
left: 0.3em;
|
||||
}
|
||||
}
|
||||
|
||||
.selectContainer-inline > .selectArrowContainer {
|
||||
|
|
|
@ -5,6 +5,7 @@ import keyboardnavigation from '../../scripts/keyboardNavigation';
|
|||
import './emby-slider.scss';
|
||||
import 'webcomponents.js/webcomponents-lite';
|
||||
import '../emby-input/emby-input';
|
||||
import globalize from '../../scripts/globalize';
|
||||
|
||||
/* eslint-disable indent */
|
||||
|
||||
|
@ -31,6 +32,8 @@ import '../emby-input/emby-input';
|
|||
const rect = range.sliderBubbleTrack.getBoundingClientRect();
|
||||
|
||||
let fraction = (clientX - rect.left) / rect.width;
|
||||
if (globalize.getIsElementRTL(range))
|
||||
fraction = (rect.right - clientX) / rect.width;
|
||||
|
||||
// Snap to step
|
||||
const valueRange = range.max - range.min;
|
||||
|
@ -118,6 +121,9 @@ import '../emby-input/emby-input';
|
|||
const bubbleRect = bubble.getBoundingClientRect();
|
||||
|
||||
let bubblePos = bubbleTrackRect.width * value / 100;
|
||||
if (globalize.getIsElementRTL(range)) {
|
||||
bubblePos = bubbleTrackRect.width - bubblePos;
|
||||
}
|
||||
bubblePos = Math.min(Math.max(bubblePos, bubbleRect.width / 2), bubbleTrackRect.width - bubbleRect.width / 2);
|
||||
|
||||
bubble.style.left = bubblePos + 'px';
|
||||
|
@ -484,7 +490,10 @@ import '../emby-input/emby-input';
|
|||
|
||||
function setRange(elem, startPercent, endPercent) {
|
||||
const style = elem.style;
|
||||
style.left = Math.max(startPercent, 0) + '%';
|
||||
if (globalize.getIsRTL())
|
||||
style.right = Math.max(startPercent, 0) + '%';
|
||||
else
|
||||
style.left = Math.max(startPercent, 0) + '%';
|
||||
|
||||
const widthPercent = endPercent - startPercent;
|
||||
style.width = Math.max(Math.min(widthPercent, 100), 0) + '%';
|
||||
|
|
|
@ -151,9 +151,16 @@
|
|||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
padding: 0 0.54em; /* half of slider thumb size */
|
||||
|
||||
[dir="ltr"] & {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mdl-slider-background-flex {
|
||||
|
@ -162,11 +169,18 @@
|
|||
margin-top: -0.1em;
|
||||
width: 100%;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
|
||||
[dir="ltr"] & {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mdl-slider-background-flex-inner {
|
||||
|
@ -177,11 +191,18 @@
|
|||
.mdl-slider-background-lower {
|
||||
/* transition: width 0.18s cubic-bezier(0.4, 0, 0.2, 1); */
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: #00a4dc;
|
||||
|
||||
[dir="ltr"] & {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mdl-slider-background-lower-clear {
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
.mdl-switch__thumb {
|
||||
background: #999;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: -0.25em;
|
||||
height: 1.44em;
|
||||
width: 1.44em;
|
||||
|
@ -72,6 +71,14 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
[dir="ltr"] & {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
[dir="rtl"] & {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mdl-switch__input:checked + .mdl-switch__label + .mdl-switch__trackContainer > .mdl-switch__thumb {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue