mirror of
https://github.com/elyby/accounts-frontend.git
synced 2025-05-31 14:11:58 +05:30
Merge branch 'account_deletion' into master
This commit is contained in:
27
packages/app/components/ui/PseudoAvatar.tsx
Normal file
27
packages/app/components/ui/PseudoAvatar.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React, { ComponentType } from 'react';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import styles from './pseudoAvatar.scss';
|
||||
|
||||
interface Props {
|
||||
index?: number;
|
||||
deleted?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const PseudoAvatar: ComponentType<Props> = ({ index = 0, deleted, className }) => (
|
||||
<div
|
||||
className={clsx(
|
||||
styles.pseudoAvatarWrapper,
|
||||
{
|
||||
[styles.deletedPseudoAvatar]: deleted,
|
||||
},
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div className={clsx(styles.pseudoAvatar, styles[`pseudoAvatar${index % 7}`])} />
|
||||
{deleted ? <div className={styles.deletedIcon} /> : ''}
|
||||
</div>
|
||||
);
|
||||
|
||||
export default PseudoAvatar;
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, { InputHTMLAttributes, MouseEventHandler } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { MessageDescriptor } from 'react-intl';
|
||||
import ClickAwayListener from 'react-click-away-listener';
|
||||
import clsx from 'clsx';
|
||||
|
||||
import { COLOR_GREEN, Color } from 'app/components/ui';
|
||||
|
||||
import styles from './dropdown.scss';
|
||||
@@ -12,7 +13,7 @@ type ItemLabel = I18nString | React.ReactElement;
|
||||
|
||||
interface Props extends InputHTMLAttributes<HTMLInputElement> {
|
||||
label: I18nString;
|
||||
items: { [value: string]: ItemLabel };
|
||||
items: Record<string, ItemLabel>;
|
||||
block?: boolean;
|
||||
color: Color;
|
||||
}
|
||||
@@ -37,18 +38,6 @@ export default class Dropdown extends FormInputComponent<Props, State> {
|
||||
activeItem: null,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
// listen to capturing phase to ensure, that our event handler will be
|
||||
// called before all other
|
||||
// @ts-ignore
|
||||
document.addEventListener('click', this.onBodyClick, true);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
// @ts-ignore
|
||||
document.removeEventListener('click', this.onBodyClick);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { color, block, items, ...restProps } = this.props;
|
||||
const { isActive } = this.state;
|
||||
@@ -59,7 +48,7 @@ export default class Dropdown extends FormInputComponent<Props, State> {
|
||||
const label = React.isValidElement(activeItem.label) ? activeItem.label : this.formatMessage(activeItem.label);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ClickAwayListener onClickAway={this.onCloseClick}>
|
||||
<div
|
||||
className={clsx(styles[color], {
|
||||
[styles.block]: block,
|
||||
@@ -84,7 +73,7 @@ export default class Dropdown extends FormInputComponent<Props, State> {
|
||||
</div>
|
||||
|
||||
{this.renderError()}
|
||||
</div>
|
||||
</ClickAwayListener>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -137,17 +126,9 @@ export default class Dropdown extends FormInputComponent<Props, State> {
|
||||
this.toggle();
|
||||
};
|
||||
|
||||
onBodyClick: MouseEventHandler = (event) => {
|
||||
onCloseClick = () => {
|
||||
if (this.state.isActive) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const el = ReactDOM.findDOMNode(this)!;
|
||||
|
||||
if (!el.contains(event.target as HTMLElement) && el !== event.target) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
this.toggle();
|
||||
}
|
||||
this.toggle();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,3 +30,4 @@ export const SKIN_LIGHT: Skin = 'light';
|
||||
export const skins: Array<Skin> = [SKIN_DARK, SKIN_LIGHT];
|
||||
|
||||
export { default as RelativeTime } from './RelativeTime';
|
||||
export { default as PseudoAvatar } from './PseudoAvatar';
|
||||
|
||||
@@ -9,10 +9,11 @@ import styles from './componentLoader.scss';
|
||||
|
||||
interface Props {
|
||||
skin?: Skin;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const ComponentLoader: ComponentType<Props> = ({ skin = 'dark' }) => (
|
||||
<div className={clsx(styles.componentLoader, styles[`${skin}ComponentLoader`])}>
|
||||
const ComponentLoader: ComponentType<Props> = ({ skin = 'dark', className }) => (
|
||||
<div className={clsx(styles.componentLoader, styles[`${skin}ComponentLoader`], className)}>
|
||||
<div className={styles.spins}>
|
||||
{new Array(5).fill(0).map((_, index) => (
|
||||
<div className={clsx(styles.spin, styles[`spin${index}`])} key={index} />
|
||||
|
||||
@@ -1,41 +1,31 @@
|
||||
@import '~app/components/ui/colors.scss';
|
||||
|
||||
.componentLoader {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.spins {
|
||||
height: 40px;
|
||||
height: 2em;
|
||||
display: flex;
|
||||
flex-shrink: 1;
|
||||
flex-basis: 0;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.spin {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
display: inline-block;
|
||||
margin: 10px 2px;
|
||||
margin: 0.5em 0.1em;
|
||||
opacity: 0;
|
||||
animation: loaderAnimation 1s infinite;
|
||||
}
|
||||
|
||||
.spin1 {
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.spin2 {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
|
||||
.spin3 {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
.spin4 {
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
|
||||
.spin5 {
|
||||
animation-delay: 0.4s;
|
||||
@for $i from 0 to 5 {
|
||||
.spin#{$i} {
|
||||
animation-delay: 0.1s * $i;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
53
packages/app/components/ui/pseudoAvatar.scss
Normal file
53
packages/app/components/ui/pseudoAvatar.scss
Normal file
@@ -0,0 +1,53 @@
|
||||
@import '~app/components/ui/colors.scss';
|
||||
|
||||
.pseudoAvatarWrapper {
|
||||
position: relative;
|
||||
display: inline-flex; // Needed to get right position of the cross icon
|
||||
}
|
||||
|
||||
.pseudoAvatar {
|
||||
composes: minecraft-character from '~app/components/ui/icons.scss';
|
||||
font-size: 1em;
|
||||
|
||||
&0 {
|
||||
color: $green;
|
||||
}
|
||||
|
||||
&1 {
|
||||
color: $blue;
|
||||
}
|
||||
|
||||
&2 {
|
||||
color: $violet;
|
||||
}
|
||||
|
||||
&3 {
|
||||
color: $orange;
|
||||
}
|
||||
|
||||
&4 {
|
||||
color: $dark_blue;
|
||||
}
|
||||
|
||||
&5 {
|
||||
color: $light_violet;
|
||||
}
|
||||
|
||||
&6 {
|
||||
color: $red;
|
||||
}
|
||||
|
||||
.deletedPseudoAvatar & {
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
.deletedIcon {
|
||||
composes: close from '~app/components/ui/icons.scss';
|
||||
|
||||
position: absolute;
|
||||
top: 0.16em;
|
||||
left: -0.145em;
|
||||
font-size: 0.7em;
|
||||
color: rgba($red, 0.75);
|
||||
}
|
||||
Reference in New Issue
Block a user