spinner
This commit is contained in:
@@ -1,9 +1,15 @@
|
|||||||
import { useMe } from '@features/auth'
|
import { useMe } from '@features/auth'
|
||||||
|
import { Spinner } from '@shared/ui'
|
||||||
import { ConverterSection } from '@widgets/converter-page'
|
import { ConverterSection } from '@widgets/converter-page'
|
||||||
import { LegalConverterPage } from './LegalConverterPage'
|
import { LegalConverterPage } from './LegalConverterPage'
|
||||||
|
|
||||||
export function ConverterPage() {
|
export function ConverterPage() {
|
||||||
const { data } = useMe()
|
const { data, isLoading } = useMe()
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return <Spinner fullscreen size="lg" label="Загрузка данных аккаунта" />
|
||||||
|
}
|
||||||
|
|
||||||
const isLegal = !!data && data.account_type !== 'individual'
|
const isLegal = !!data && data.account_type !== 'individual'
|
||||||
return isLegal ? <LegalConverterPage /> : <ConverterSection />
|
return isLegal ? <LegalConverterPage /> : <ConverterSection />
|
||||||
}
|
}
|
||||||
|
|||||||
71
src/shared/ui/Spinner/Spinner.module.css
Normal file
71
src/shared/ui/Spinner/Spinner.module.css
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
.wrap {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
display: block;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 2px solid var(--glass-border);
|
||||||
|
border-top-color: var(--highlight);
|
||||||
|
animation: spin 0.7s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sizes */
|
||||||
|
.sm {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border-width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-width: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lg {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-width: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
letter-spacing: 0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.srOnly {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
padding: 0;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.spinner {
|
||||||
|
animation-duration: 1.6s;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/shared/ui/Spinner/Spinner.tsx
Normal file
27
src/shared/ui/Spinner/Spinner.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import styles from './Spinner.module.css'
|
||||||
|
|
||||||
|
type SpinnerSize = 'sm' | 'md' | 'lg'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/** Размер спиннера. По умолчанию `md`. */
|
||||||
|
size?: SpinnerSize
|
||||||
|
/** Подпись под спиннером. */
|
||||||
|
label?: string
|
||||||
|
/** Растянуть на всю высоту контейнера и отцентрировать содержимое. */
|
||||||
|
fullscreen?: boolean
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Spinner({ size = 'md', label, fullscreen, className }: Props) {
|
||||||
|
const wrapClass = [styles.wrap, fullscreen ? styles.fullscreen : '', className ?? '']
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(' ')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={wrapClass} role="status" aria-live="polite" aria-busy="true">
|
||||||
|
<span className={`${styles.spinner} ${styles[size]}`} aria-hidden="true" />
|
||||||
|
{label ? <span className={styles.label}>{label}</span> : null}
|
||||||
|
<span className={styles.srOnly}>{label ?? 'Загрузка'}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
1
src/shared/ui/Spinner/index.ts
Normal file
1
src/shared/ui/Spinner/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { Spinner } from './Spinner'
|
||||||
@@ -8,4 +8,5 @@ export { Pill } from './Pill'
|
|||||||
export { PrimaryButton } from './PrimaryButton'
|
export { PrimaryButton } from './PrimaryButton'
|
||||||
export { Select } from './Select'
|
export { Select } from './Select'
|
||||||
export type { SelectOption } from './Select'
|
export type { SelectOption } from './Select'
|
||||||
|
export { Spinner } from './Spinner'
|
||||||
export { TokenIcon } from './TokenIcon'
|
export { TokenIcon } from './TokenIcon'
|
||||||
|
|||||||
Reference in New Issue
Block a user