Skip to content

Commit

Permalink
fix: carousel skeleton size
Browse files Browse the repository at this point in the history
  • Loading branch information
siandreev committed Jan 22, 2024
1 parent 6a47228 commit 53db3ce
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 111 deletions.
3 changes: 2 additions & 1 deletion apps/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import { GlobalListStyle } from '@tonkeeper/uikit/dist/components/List';
import { Loading } from '@tonkeeper/uikit/dist/components/Loading';
import MemoryScroll from '@tonkeeper/uikit/dist/components/MemoryScroll';
import {
ActivitySkeletonPage, BrowserSkeletonPage,
ActivitySkeletonPage,
BrowserSkeletonPage,
CoinSkeletonPage,
HomeSkeleton,
SettingsSkeletonPage
Expand Down
2 changes: 1 addition & 1 deletion packages/uikit/src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { H1, H3, Label1, Label2 } from './Text';
import { ScanButton } from './connect/ScanButton';
import { ImportNotification } from './create/ImportNotification';
import { useUserCountry } from '../state/country';
import { SkeletonText } from './Skeleton';
import { SkeletonText } from './shared/Skeleton';

const Block = styled.div<{
center?: boolean;
Expand Down
105 changes: 5 additions & 100 deletions packages/uikit/src/components/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -1,113 +1,18 @@
import React, { FC, useEffect } from 'react';
import styled, { css } from 'styled-components';
import styled from 'styled-components';
import { useAppSdk } from '../hooks/appSdk';
import { InnerBody } from './Body';
import { ActivityHeader, BrowserHeader, SettingsHeader } from './Header';
import {ActivityHeader, BrowserHeader, SettingsHeader} from './Header';
import { ActionsRow } from './home/Actions';
import { BalanceSkeleton } from './home/Balance';
import { CoinInfoSkeleton } from './jettons/Info';
import { ColumnText } from './Layout';
import { ListBlock, ListItem, ListItemPayload } from './List';
import { SubHeader } from './SubHeader';
import { H3 } from './Text';
import { RecommendationsPageBodySkeleton } from './skeletons/BrowserSkeletons';

function randomIntFromInterval(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1) + min);
}

function randomWidth() {
return randomIntFromInterval(30, 90) + '%';
}

const Base = styled.div`
display: inline-block;
@keyframes placeHolderShimmer {
0% {
background-position: -800px 0;
}
100% {
background-position: 800px 0;
}
}
animation-duration: 2s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background-color: #f6f7f8;
background: linear-gradient(to right, #4f5a70 8%, #bbbbbb 18%, #4f5a70 33%);
background-size: 800px 104px;
opacity: 0.1;
position: relative;
`;
const Block = styled(Base)<{ size?: string; width?: string }>`
border-radius: ${props => props.theme.cornerExtraExtraSmall};
${props => css`
width: ${props.width ?? randomWidth()};
`}
${props => {
switch (props.size) {
case 'large':
return css`
height: 1.5rem;
`;
case 'small':
return css`
height: 0.5rem;
`;
default:
return css`
height: 1rem;
`;
}
}}
`;

export const SkeletonText: FC<{ size?: 'large' | 'small'; width?: string; className?: string }> =
React.memo(({ size, width, className }) => {
return <Block size={size} width={width} className={className} />;
});

export const Skeleton = styled(Base)<{
width: string;
height: string;
borderRadius?: string;
margin?: string;
marginBottom?: string;
}>`
display: block;
border-radius: ${props =>
props.borderRadius
? props.theme[props.borderRadius] || props.theme.cornerExtraExtraSmall
: props.theme.cornerExtraExtraSmall};
${props => css`
width: ${props.width ?? '3rem'};
height: ${props.height ?? '20px'};
${props.margin && `margin: ${props.margin};`}
${props.marginBottom && `margin-bottom: ${props.marginBottom};`}
`}
`;

const Image = styled(Base)<{ width?: string }>`
border-radius: ${props => props.theme.cornerFull};
${props => css`
width: ${props.width ?? '44px'};
height: ${props.width ?? '44px'};
`}
`;

export const SkeletonImage: FC<{ width?: string }> = React.memo(({ width }) => {
return <Image width={width} />;
});
import { SkeletonImage, SkeletonText } from './shared/Skeleton';
import {randomIntFromInterval} from "../libs/common";
import {RecommendationsPageBodySkeleton} from "./skeletons/BrowserSkeletons";

export const SkeletonSubHeader = React.memo(() => {
return <SubHeader title={<SkeletonText size="large" />} />;
Expand Down
2 changes: 1 addition & 1 deletion packages/uikit/src/components/home/Balance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { formatFiatCurrency } from '../../hooks/balance';
import { useTranslation } from '../../hooks/translation';
import { QueryKey } from '../../libs/queryKey';
import { TokenRate, getRateKey } from '../../state/rates';
import { SkeletonText } from '../Skeleton';
import { SkeletonText } from '../shared/Skeleton';
import { Body3, Label2, Num2 } from '../Text';
import { AssetData } from './Jettons';

Expand Down
2 changes: 1 addition & 1 deletion packages/uikit/src/components/jettons/Info.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { FC } from 'react';
import styled from 'styled-components';
import { SkeletonImage, SkeletonText } from '../Skeleton';
import { SkeletonImage, SkeletonText } from '../shared/Skeleton';
import { H2 } from '../Text';
import { Body } from './CroppedText';

Expand Down
96 changes: 96 additions & 0 deletions packages/uikit/src/components/shared/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import styled, { css } from 'styled-components';
import React, { FC } from 'react';
import { randomIntFromInterval } from '../../libs/common';

function randomWidth() {
return randomIntFromInterval(30, 90) + '%';
}

const Base = styled.div`
display: inline-block;
@keyframes placeHolderShimmer {
0% {
background-position: -800px 0;
}
100% {
background-position: 800px 0;
}
}
animation-duration: 2s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: placeHolderShimmer;
animation-timing-function: linear;
background-color: #f6f7f8;
background: linear-gradient(to right, #4f5a70 8%, #bbbbbb 18%, #4f5a70 33%);
background-size: 800px 104px;
opacity: 0.1;
position: relative;
`;
const Block = styled(Base)<{ size?: string; width?: string }>`
border-radius: ${props => props.theme.cornerExtraExtraSmall};
${props => css`
width: ${props.width ?? randomWidth()};
`}
${props => {
switch (props.size) {
case 'large':
return css`
height: 1.5rem;
`;
case 'small':
return css`
height: 0.5rem;
`;
default:
return css`
height: 1rem;
`;
}
}}
`;

export const SkeletonText: FC<{ size?: 'large' | 'small'; width?: string; className?: string }> =
React.memo(({ size, width, className }) => {
return <Block size={size} width={width} className={className} />;
});

export const Skeleton = styled(Base)<{
width: string;
height?: string;
borderRadius?: string;
margin?: string;
marginBottom?: string;
}>`
display: block;
border-radius: ${props =>
props.borderRadius
? props.theme[props.borderRadius] || props.theme.cornerExtraExtraSmall
: props.theme.cornerExtraExtraSmall};
${props => css`
width: ${props.width ?? '3rem'};
height: ${props.height ?? '20px'};
${props.margin && `margin: ${props.margin};`}
${props.marginBottom && `margin-bottom: ${props.marginBottom};`}
`}
`;

const Image = styled(Base)<{ width?: string }>`
border-radius: ${props => props.theme.cornerFull};
${props => css`
width: ${props.width ?? '44px'};
height: ${props.width ?? '44px'};
`}
`;

export const SkeletonImage: FC<{ width?: string }> = React.memo(({ width }) => {
return <Image width={width} />;
});
14 changes: 7 additions & 7 deletions packages/uikit/src/components/skeletons/BrowserSkeletons.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { PromotedItem, PromotedItemText } from '../../pages/browser/PromotedItem';
import { Skeleton } from '../Skeleton';
import { Skeleton } from '../shared/Skeleton';
import React, { FC } from 'react';
import { ListBlock, ListItem } from '../List';
import styled from 'styled-components';
Expand All @@ -16,15 +16,15 @@ const Heading = styled.div`
gap: 1rem;
`;

const CarouselSkeleton = styled(Skeleton)`
height: auto;
aspect-ratio: 2 / 1;
`;

export const RecommendationsPageBodySkeleton: FC = () => {
return (
<>
<Skeleton
width="448px"
height="224px"
borderRadius="cornerSmall"
margin="0 auto 1rem"
/>
<CarouselSkeleton width="100%" borderRadius="cornerSmall" margin="0 auto 1rem" />
<CategorySkeleton />
<CategorySkeleton />
</>
Expand Down
4 changes: 4 additions & 0 deletions packages/uikit/src/libs/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ export function mergeRefs<T>(...inputRefs: (Ref<T> | undefined)[]): Ref<T> | Ref
});
};
}

export function randomIntFromInterval(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1) + min);
}

0 comments on commit 53db3ce

Please sign in to comment.