Change prettier rules

This commit is contained in:
ErickSkrauch
2020-05-24 02:08:24 +03:00
parent 73f0c37a6a
commit f85b9d8d35
382 changed files with 24137 additions and 26046 deletions

View File

@@ -1,12 +1,12 @@
import React, { MouseEventHandler } from 'react';
import {
TransitionMotion,
spring,
presets,
TransitionStyle,
TransitionPlainStyle,
PlainStyle,
Style,
TransitionMotion,
spring,
presets,
TransitionStyle,
TransitionPlainStyle,
PlainStyle,
Style,
} from 'react-motion';
import { FormattedMessage as Message } from 'react-intl';
import clsx from 'clsx';
@@ -22,161 +22,157 @@ import biteMyShinyMetalAss from './images/bite_my_shiny_metal_ass.svg';
import iTookAnArrowInMyKnee from './images/i_took_an_arrow_in_my_knee.svg';
interface EmptyCaption {
src: string;
caption: string;
src: string;
caption: string;
}
const emptyCaptions: ReadonlyArray<EmptyCaption> = [
{
// Homestuck
src: thatFuckingPumpkin,
caption: 'That fucking pumpkin',
},
{
// Star Wars
src: mayTheForceBeWithYou,
caption: 'May The Force Be With You',
},
{
// Futurama
src: biteMyShinyMetalAss,
caption: 'Bite my shiny metal ass',
},
{
// The Elder Scrolls V: Skyrim
src: iTookAnArrowInMyKnee,
caption: 'I took an arrow in my knee',
},
{
// Homestuck
src: thatFuckingPumpkin,
caption: 'That fucking pumpkin',
},
{
// Star Wars
src: mayTheForceBeWithYou,
caption: 'May The Force Be With You',
},
{
// Futurama
src: biteMyShinyMetalAss,
caption: 'Bite my shiny metal ass',
},
{
// The Elder Scrolls V: Skyrim
src: iTookAnArrowInMyKnee,
caption: 'I took an arrow in my knee',
},
];
const itemHeight = 51;
export default class LanguageList extends React.Component<{
selectedLocale: string;
langs: LocalesMap;
onChangeLang: (lang: string) => void;
selectedLocale: string;
langs: LocalesMap;
onChangeLang: (lang: string) => void;
}> {
emptyListStateInner: HTMLDivElement | null;
emptyListStateInner: HTMLDivElement | null;
render() {
const { selectedLocale, langs } = this.props;
const isListEmpty = Object.keys(langs).length === 0;
const firstLocale = Object.keys(langs)[0] || null;
const emptyCaption = this.getEmptyCaption();
render() {
const { selectedLocale, langs } = this.props;
const isListEmpty = Object.keys(langs).length === 0;
const firstLocale = Object.keys(langs)[0] || null;
const emptyCaption = this.getEmptyCaption();
return (
<TransitionMotion
defaultStyles={this.getItemsWithDefaultStyles()}
styles={this.getItemsWithStyles()}
willLeave={this.willLeave}
willEnter={this.willEnter}
>
{(items) => (
<div className={styles.languagesList} data-testid="language-list">
<div
className={clsx(styles.emptyLanguagesListWrapper, {
[styles.emptyLanguagesListVisible]: isListEmpty,
})}
style={{
height:
isListEmpty && this.emptyListStateInner
? this.emptyListStateInner.clientHeight
: 0,
}}
return (
<TransitionMotion
defaultStyles={this.getItemsWithDefaultStyles()}
styles={this.getItemsWithStyles()}
willLeave={this.willLeave}
willEnter={this.willEnter}
>
<div
ref={(elem: HTMLDivElement | null) =>
(this.emptyListStateInner = elem)
}
className={styles.emptyLanguagesList}
>
<img
src={emptyCaption.src}
alt={emptyCaption.caption}
className={styles.emptyLanguagesListCaption}
/>
<div className={styles.emptyLanguagesListSubtitle}>
<Message {...messages.weDoNotSupportThisLang} />
</div>
</div>
</div>
{(items) => (
<div className={styles.languagesList} data-testid="language-list">
<div
className={clsx(styles.emptyLanguagesListWrapper, {
[styles.emptyLanguagesListVisible]: isListEmpty,
})}
style={{
height:
isListEmpty && this.emptyListStateInner ? this.emptyListStateInner.clientHeight : 0,
}}
>
<div
ref={(elem: HTMLDivElement | null) => (this.emptyListStateInner = elem)}
className={styles.emptyLanguagesList}
>
<img
src={emptyCaption.src}
alt={emptyCaption.caption}
className={styles.emptyLanguagesListCaption}
/>
<div className={styles.emptyLanguagesListSubtitle}>
<Message {...messages.weDoNotSupportThisLang} />
</div>
</div>
</div>
{items.map(({ key: locale, data: definition, style }) => (
<div
key={locale}
style={style}
className={clsx(styles.languageItem, {
[styles.activeLanguageItem]: locale === selectedLocale,
[styles.firstLanguageItem]: locale === firstLocale,
})}
onClick={this.onChangeLang(locale)}
>
<LocaleItem locale={definition} />
</div>
))}
</div>
)}
</TransitionMotion>
);
}
{items.map(({ key: locale, data: definition, style }) => (
<div
key={locale}
style={style}
className={clsx(styles.languageItem, {
[styles.activeLanguageItem]: locale === selectedLocale,
[styles.firstLanguageItem]: locale === firstLocale,
})}
onClick={this.onChangeLang(locale)}
>
<LocaleItem locale={definition} />
</div>
))}
</div>
)}
</TransitionMotion>
);
}
getEmptyCaption(): EmptyCaption {
return emptyCaptions[Math.floor(Math.random() * emptyCaptions.length)];
}
getEmptyCaption(): EmptyCaption {
return emptyCaptions[Math.floor(Math.random() * emptyCaptions.length)];
}
onChangeLang(lang: string): MouseEventHandler<HTMLDivElement> {
return (event) => {
event.preventDefault();
onChangeLang(lang: string): MouseEventHandler<HTMLDivElement> {
return (event) => {
event.preventDefault();
this.props.onChangeLang(lang);
this.props.onChangeLang(lang);
};
}
getItemsWithDefaultStyles = (): Array<TransitionPlainStyle> => {
return Object.keys({ ...this.props.langs }).reduce(
(previous, key) => [
...previous,
{
key,
data: this.props.langs[key],
style: {
height: itemHeight,
opacity: 1,
},
},
],
[] as Array<TransitionPlainStyle>,
);
};
}
getItemsWithDefaultStyles = (): Array<TransitionPlainStyle> => {
return Object.keys({ ...this.props.langs }).reduce(
(previous, key) => [
...previous,
{
key,
data: this.props.langs[key],
style: {
height: itemHeight,
getItemsWithStyles = (): Array<TransitionStyle> => {
return Object.keys({ ...this.props.langs }).reduce(
(previous, key) => [
...previous,
{
key,
data: this.props.langs[key],
style: {
height: spring(itemHeight, presets.gentle),
opacity: spring(1, presets.gentle),
},
},
],
[] as Array<TransitionStyle>,
);
};
willEnter(): PlainStyle {
return {
height: 0,
opacity: 1,
},
},
],
[] as Array<TransitionPlainStyle>,
);
};
};
}
getItemsWithStyles = (): Array<TransitionStyle> => {
return Object.keys({ ...this.props.langs }).reduce(
(previous, key) => [
...previous,
{
key,
data: this.props.langs[key],
style: {
height: spring(itemHeight, presets.gentle),
opacity: spring(1, presets.gentle),
},
},
],
[] as Array<TransitionStyle>,
);
};
willEnter(): PlainStyle {
return {
height: 0,
opacity: 1,
};
}
willLeave(): Style {
return {
height: spring(0),
opacity: spring(0),
};
}
willLeave(): Style {
return {
height: spring(0),
opacity: spring(0),
};
}
}

View File

@@ -16,164 +16,158 @@ import { RootState } from 'app/reducers';
const translateUrl = 'http://ely.by/translate';
export interface LocaleData {
code: string;
name: string;
englishName: string;
progress: number;
isReleased: boolean;
code: string;
name: string;
englishName: string;
progress: number;
isReleased: boolean;
}
export type LocalesMap = Record<string, LocaleData>;
type OwnProps = {
onClose: () => void;
langs: LocalesMap;
emptyCaptions: Array<{
src: string;
caption: string;
}>;
onClose: () => void;
langs: LocalesMap;
emptyCaptions: Array<{
src: string;
caption: string;
}>;
};
interface Props extends OwnProps {
intl: IntlShape;
selectedLocale: string;
changeLang: (lang: string) => void;
intl: IntlShape;
selectedLocale: string;
changeLang: (lang: string) => void;
}
class LanguageSwitcher extends React.Component<
Props,
{
filter: string;
filteredLangs: LocalesMap;
}
Props,
{
filter: string;
filteredLangs: LocalesMap;
}
> {
state = {
filter: '',
filteredLangs: this.props.langs,
};
static defaultProps = {
langs: LANGS,
onClose() {},
};
render() {
const { selectedLocale, onClose, intl } = this.props;
const { filteredLangs } = this.state;
return (
<div
className={styles.languageSwitcher}
data-testid="language-switcher"
data-e2e-active-locale={selectedLocale}
>
<div className={popupStyles.popup}>
<div className={popupStyles.header}>
<h2 className={popupStyles.headerTitle}>
<Message {...messages.siteLanguage} />
</h2>
<span
className={clsx(icons.close, popupStyles.close)}
onClick={onClose}
/>
</div>
<div className={styles.languageSwitcherBody}>
<div className={styles.searchBox}>
<input
className={clsx(
formStyles.lightTextField,
formStyles.greenTextField,
)}
placeholder={intl.formatMessage(messages.startTyping)}
onChange={this.onFilterUpdate}
onKeyPress={this.onFilterKeyPress()}
autoFocus
/>
<span className={styles.searchIcon} />
</div>
<LanguageList
selectedLocale={selectedLocale}
langs={filteredLangs}
onChangeLang={this.onChangeLang}
/>
<div className={styles.improveTranslates}>
<div className={styles.improveTranslatesIcon} />
<div className={styles.improveTranslatesContent}>
<div className={styles.improveTranslatesTitle}>
<Message {...messages.improveTranslates} />
</div>
<div className={styles.improveTranslatesText}>
<Message {...messages.improveTranslatesDescription} />{' '}
<a href={translateUrl} target="_blank">
<Message {...messages.improveTranslatesParticipate} />
</a>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
onChangeLang = this.changeLang.bind(this);
changeLang(lang: string) {
this.props.changeLang(lang);
setTimeout(this.props.onClose, 300);
}
onFilterUpdate = (event: React.ChangeEvent<HTMLInputElement>) => {
const filter = event.currentTarget.value.trim().toLowerCase();
const { langs } = this.props;
const result = Object.keys(langs).reduce((previous, key) => {
if (
langs[key].englishName.toLowerCase().indexOf(filter) === -1 &&
langs[key].name.toLowerCase().indexOf(filter) === -1
) {
return previous;
}
previous[key] = langs[key];
return previous;
}, {} as typeof langs);
this.setState({
filter,
filteredLangs: result,
});
};
onFilterKeyPress() {
return (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key !== 'Enter' || this.state.filter === '') {
return;
}
const locales = Object.keys(this.state.filteredLangs);
if (locales.length === 0) {
return;
}
this.changeLang(locales[0]);
state = {
filter: '',
filteredLangs: this.props.langs,
};
}
static defaultProps = {
langs: LANGS,
onClose() {},
};
render() {
const { selectedLocale, onClose, intl } = this.props;
const { filteredLangs } = this.state;
return (
<div
className={styles.languageSwitcher}
data-testid="language-switcher"
data-e2e-active-locale={selectedLocale}
>
<div className={popupStyles.popup}>
<div className={popupStyles.header}>
<h2 className={popupStyles.headerTitle}>
<Message {...messages.siteLanguage} />
</h2>
<span className={clsx(icons.close, popupStyles.close)} onClick={onClose} />
</div>
<div className={styles.languageSwitcherBody}>
<div className={styles.searchBox}>
<input
className={clsx(formStyles.lightTextField, formStyles.greenTextField)}
placeholder={intl.formatMessage(messages.startTyping)}
onChange={this.onFilterUpdate}
onKeyPress={this.onFilterKeyPress()}
autoFocus
/>
<span className={styles.searchIcon} />
</div>
<LanguageList
selectedLocale={selectedLocale}
langs={filteredLangs}
onChangeLang={this.onChangeLang}
/>
<div className={styles.improveTranslates}>
<div className={styles.improveTranslatesIcon} />
<div className={styles.improveTranslatesContent}>
<div className={styles.improveTranslatesTitle}>
<Message {...messages.improveTranslates} />
</div>
<div className={styles.improveTranslatesText}>
<Message {...messages.improveTranslatesDescription} />{' '}
<a href={translateUrl} target="_blank">
<Message {...messages.improveTranslatesParticipate} />
</a>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
onChangeLang = this.changeLang.bind(this);
changeLang(lang: string) {
this.props.changeLang(lang);
setTimeout(this.props.onClose, 300);
}
onFilterUpdate = (event: React.ChangeEvent<HTMLInputElement>) => {
const filter = event.currentTarget.value.trim().toLowerCase();
const { langs } = this.props;
const result = Object.keys(langs).reduce((previous, key) => {
if (
langs[key].englishName.toLowerCase().indexOf(filter) === -1 &&
langs[key].name.toLowerCase().indexOf(filter) === -1
) {
return previous;
}
previous[key] = langs[key];
return previous;
}, {} as typeof langs);
this.setState({
filter,
filteredLangs: result,
});
};
onFilterKeyPress() {
return (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key !== 'Enter' || this.state.filter === '') {
return;
}
const locales = Object.keys(this.state.filteredLangs);
if (locales.length === 0) {
return;
}
this.changeLang(locales[0]);
};
}
}
export default injectIntl(
connect(
(state: RootState) => ({
selectedLocale: state.i18n.locale,
}),
{
changeLang,
},
)(LanguageSwitcher),
connect(
(state: RootState) => ({
selectedLocale: state.i18n.locale,
}),
{
changeLang,
},
)(LanguageSwitcher),
);

View File

@@ -7,44 +7,42 @@ import styles from './languageSwitcher.scss';
import { LocaleData } from './LanguageSwitcher';
interface Props {
locale: LocaleData;
locale: LocaleData;
}
const LocaleItem: ComponentType<Props> = ({
locale: { code, name, englishName, progress, isReleased },
}) => {
let progressLabel: ReactNode;
const LocaleItem: ComponentType<Props> = ({ locale: { code, name, englishName, progress, isReleased } }) => {
let progressLabel: ReactNode;
if (progress !== 100) {
progressLabel = (
<Message
{...messages.translationProgress}
values={{
progress,
}}
/>
);
} else if (!isReleased) {
progressLabel = <Message {...messages.mayBeInaccurate} />;
}
if (progress !== 100) {
progressLabel = (
<Message
{...messages.translationProgress}
values={{
progress,
}}
/>
);
} else if (!isReleased) {
progressLabel = <Message {...messages.mayBeInaccurate} />;
}
return (
<div className={styles.languageFlex}>
<div
className={styles.languageIco}
style={{
backgroundImage: `url('${localeFlags.getIconUrl(code)}')`,
}}
/>
<div className={styles.languageCaptions}>
<div className={styles.languageName}>{name}</div>
<div className={styles.languageSubName}>
{englishName} {progressLabel ? '| ' : ''} {progressLabel}
return (
<div className={styles.languageFlex}>
<div
className={styles.languageIco}
style={{
backgroundImage: `url('${localeFlags.getIconUrl(code)}')`,
}}
/>
<div className={styles.languageCaptions}>
<div className={styles.languageName}>{name}</div>
<div className={styles.languageSubName}>
{englishName} {progressLabel ? '| ' : ''} {progressLabel}
</div>
</div>
<span className={styles.languageCircle} />
</div>
</div>
<span className={styles.languageCircle} />
</div>
);
);
};
export default LocaleItem;

View File

@@ -10,34 +10,32 @@ import { RootState } from 'app/reducers';
import styles from './link.scss';
const LanguageLink: ComponentType = () => {
const dispatch = useDispatch();
const showLanguageSwitcherPopup = useCallback(() => {
dispatch(createPopup({ Popup: LanguageSwitcher }));
}, [dispatch]);
const dispatch = useDispatch();
const showLanguageSwitcherPopup = useCallback(() => {
dispatch(createPopup({ Popup: LanguageSwitcher }));
}, [dispatch]);
const userLang = useSelector((state: RootState) => state.user.lang);
const interfaceLocale = useSelector((state: RootState) => state.i18n.locale);
const userLang = useSelector((state: RootState) => state.user.lang);
const interfaceLocale = useSelector((state: RootState) => state.i18n.locale);
const localeDefinition = LANGS[userLang] || LANGS[interfaceLocale];
const localeDefinition = LANGS[userLang] || LANGS[interfaceLocale];
return (
<span
className={clsx(styles.languageLink, {
[styles.mark]: userLang !== interfaceLocale,
})}
onClick={showLanguageSwitcherPopup}
>
<span
className={styles.languageIcon}
style={{
backgroundImage: `url('${localeFlags.getIconUrl(
localeDefinition.code,
)}')`,
}}
/>
{localeDefinition.name}
</span>
);
return (
<span
className={clsx(styles.languageLink, {
[styles.mark]: userLang !== interfaceLocale,
})}
onClick={showLanguageSwitcherPopup}
>
<span
className={styles.languageIcon}
style={{
backgroundImage: `url('${localeFlags.getIconUrl(localeDefinition.code)}')`,
}}
/>
{localeDefinition.name}
</span>
);
};
export default LanguageLink;

View File

@@ -1,35 +1,35 @@
@import '~app/components/ui/colors.scss';
.languageLink {
position: relative;
position: relative;
color: #666;
border-bottom: 1px dotted #666;
text-decoration: none;
transition: 0.25s;
cursor: pointer;
color: #666;
border-bottom: 1px dotted #666;
text-decoration: none;
transition: 0.25s;
cursor: pointer;
&.mark {
&:after {
position: absolute;
content: '*';
color: $red;
font-size: 75%;
top: -0.2em;
&.mark {
&:after {
position: absolute;
content: '*';
color: $red;
font-size: 75%;
top: -0.2em;
}
}
}
}
.languageIcon {
$height: 13px;
$height: 13px;
position: relative;
top: 1px;
display: inline-block;
margin-right: 4px;
height: $height;
width: $height * 4 / 3;
box-shadow: 0 0 1px rgba(#000, 0.2);
position: relative;
top: 1px;
display: inline-block;
margin-right: 4px;
height: $height;
width: $height * 4 / 3;
box-shadow: 0 0 1px rgba(#000, 0.2);
background-size: cover;
background-size: cover;
}

View File

@@ -1,10 +1,10 @@
{
"siteLanguage": "Site language",
"startTyping": "Start typing…",
"translationProgress": "{progress}% translated",
"mayBeInaccurate": "May be inaccurate",
"weDoNotSupportThisLang": "Sorry, we do not support this language",
"improveTranslates": "Improve Ely.by translation",
"improveTranslatesDescription": "Ely.bys localization is a community effort. If you want to improve the translation of Ely.by, we'd love your help.",
"improveTranslatesParticipate": "Click here to participate."
"siteLanguage": "Site language",
"startTyping": "Start typing…",
"translationProgress": "{progress}% translated",
"mayBeInaccurate": "May be inaccurate",
"weDoNotSupportThisLang": "Sorry, we do not support this language",
"improveTranslates": "Improve Ely.by translation",
"improveTranslatesDescription": "Ely.bys localization is a community effort. If you want to improve the translation of Ely.by, we'd love your help.",
"improveTranslatesParticipate": "Click here to participate."
}

View File

@@ -3,229 +3,229 @@
@import '~app/components/ui/popup/popup.scss';
@mixin hideFooter {
@media (max-height: 455px) {
@content;
}
@media (max-height: 455px) {
@content;
}
}
.languageSwitcher {
composes: popupWrapper from '~app/components/ui/popup/popup.scss';
composes: popupWrapper from '~app/components/ui/popup/popup.scss';
@include popupBounding(400px);
@include popupBounding(400px);
}
.languageSwitcherBody {
composes: body from '~app/components/ui/popup/popup.scss';
composes: body from '~app/components/ui/popup/popup.scss';
display: flex;
flex-direction: column;
max-height: calc(100vh - 132px);
display: flex;
flex-direction: column;
max-height: calc(100vh - 132px);
@media screen and (min-height: 630px) {
max-height: 500px;
}
@media screen and (min-height: 630px) {
max-height: 500px;
}
}
.searchBox {
position: relative;
margin-bottom: 20px;
position: relative;
margin-bottom: 20px;
}
.searchIcon {
composes: search from '~app/components/ui/icons.scss';
composes: search from '~app/components/ui/icons.scss';
position: absolute;
top: 14px;
right: 12px;
font-size: 22px;
color: #edebe5;
pointer-events: none; // Иконка чисто декоративная, так что клик должен проходить сквозь неё
position: absolute;
top: 14px;
right: 12px;
font-size: 22px;
color: #edebe5;
pointer-events: none; // Иконка чисто декоративная, так что клик должен проходить сквозь неё
}
$languageListBorderColor: #eee;
$languageListBorderStyle: 1px solid $languageListBorderColor;
.languagesList {
flex-grow: 1;
overflow-y: auto;
border-top: $languageListBorderStyle;
border-bottom: $languageListBorderStyle;
margin-bottom: 20px;
flex-grow: 1;
overflow-y: auto;
border-top: $languageListBorderStyle;
border-bottom: $languageListBorderStyle;
margin-bottom: 20px;
&::-webkit-scrollbar {
width: 12px;
}
&::-webkit-scrollbar-track {
background-color: #f3f3f3;
}
&::-webkit-scrollbar-thumb {
background-color: #d8d5d0;
}
@include hideFooter {
& {
margin-bottom: 0;
&::-webkit-scrollbar {
width: 12px;
}
&::-webkit-scrollbar-track {
background-color: #f3f3f3;
}
&::-webkit-scrollbar-thumb {
background-color: #d8d5d0;
}
@include hideFooter {
& {
margin-bottom: 0;
}
}
}
}
.languageItem {
font-family: $font-family-title;
transition: background-color 0.25s;
cursor: pointer;
overflow: hidden;
line-height: 1;
font-family: $font-family-title;
transition: background-color 0.25s;
cursor: pointer;
overflow: hidden;
line-height: 1;
&:hover {
background-color: $whiteButtonLight;
}
&:hover {
background-color: $whiteButtonLight;
}
}
.languageFlex {
box-sizing: border-box;
display: flex;
align-items: center;
padding: 10px;
border-top: $languageListBorderStyle;
box-sizing: border-box;
display: flex;
align-items: center;
padding: 10px;
border-top: $languageListBorderStyle;
.firstLanguageItem & {
border-top: none;
}
.firstLanguageItem & {
border-top: none;
}
}
.languageIco {
display: inline-block;
margin-right: 7px;
width: 40px;
height: 30px;
box-shadow: 0 0 1px rgba(#000, 0.2);
display: inline-block;
margin-right: 7px;
width: 40px;
height: 30px;
box-shadow: 0 0 1px rgba(#000, 0.2);
background: no-repeat;
background-size: cover;
background: no-repeat;
background-size: cover;
}
.languageCaptions {
flex: 1;
overflow: hidden;
flex: 1;
overflow: hidden;
}
.languageName {
font-size: 15px;
margin-bottom: 2px;
font-size: 15px;
margin-bottom: 2px;
}
.languageSubName {
font-size: 11px;
color: #ccc;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 11px;
color: #ccc;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
// Реализация радио кнопки. Когда у нас будет нормальный компонент радио кнопок, нужно будет перейти на него
.languageCircle {
composes: checkmark from '~app/components/ui/icons.scss';
composes: checkmark from '~app/components/ui/icons.scss';
position: relative;
box-sizing: border-box;
width: 22px;
height: 22px;
right: -32px;
position: relative;
box-sizing: border-box;
width: 22px;
height: 22px;
right: -32px;
font-size: 10px;
line-height: 18px;
text-align: center;
color: #fff;
border: 2px solid #dcd8cd;
border-radius: 50%;
font-size: 10px;
line-height: 18px;
text-align: center;
color: #fff;
border: 2px solid #dcd8cd;
border-radius: 50%;
transition: 0.5s cubic-bezier(0.19, 1, 0.22, 1);
&:before {
opacity: 0;
transition: opacity 0.3s;
}
.languageItem:hover & {
right: 0;
}
.activeLanguageItem & {
border-color: $green;
background: $green;
right: 0;
transition: 0.5s cubic-bezier(0.19, 1, 0.22, 1);
&:before {
opacity: 1;
opacity: 0;
transition: opacity 0.3s;
}
.languageItem:hover & {
right: 0;
}
.activeLanguageItem & {
border-color: $green;
background: $green;
right: 0;
&:before {
opacity: 1;
}
}
}
}
.emptyLanguagesListWrapper {
$transitionTime: 0.5s;
$transitionTime: 0.5s;
opacity: 0;
overflow: hidden;
transition: height $transitionTime;
opacity: 0;
overflow: hidden;
transition: height $transitionTime;
&.emptyLanguagesListVisible {
opacity: 1;
transition: $transitionTime;
}
&.emptyLanguagesListVisible {
opacity: 1;
transition: $transitionTime;
}
}
.emptyLanguagesList {
padding: 20px;
text-align: center;
padding: 20px;
text-align: center;
}
.emptyLanguagesListCaption {
height: 20px;
max-width: 100%;
margin-bottom: 5px;
height: 20px;
max-width: 100%;
margin-bottom: 5px;
}
.emptyLanguagesListSubtitle {
font-family: $font-family-title;
color: #ccc;
font-size: 13px;
font-family: $font-family-title;
color: #ccc;
font-size: 13px;
}
.improveTranslates {
border: 1px solid #dedede;
background: #f3f1ed;
padding: 10px;
display: flex;
flex-shrink: 0;
border: 1px solid #dedede;
background: #f3f1ed;
padding: 10px;
display: flex;
flex-shrink: 0;
@include hideFooter {
& {
display: none;
@include hideFooter {
& {
display: none;
}
}
}
}
.improveTranslatesIcon {
composes: translate from '~app/components/ui/icons.scss';
composes: translate from '~app/components/ui/icons.scss';
color: lighter($blue);
font-size: 22px;
margin-right: 10px;
color: lighter($blue);
font-size: 22px;
margin-right: 10px;
}
.improveTranslatesContent {
}
.improveTranslatesTitle {
font-family: $font-family-title;
font-size: 13px;
margin-bottom: 3px;
font-family: $font-family-title;
font-size: 13px;
margin-bottom: 3px;
}
.improveTranslatesText {
font-size: 10px;
color: #9a9a9a;
line-height: 1.2;
font-size: 10px;
color: #9a9a9a;
line-height: 1.2;
}