react-spring#useTransition TypeScript Examples
The following examples show how to use
react-spring#useTransition.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.tsx From gobarber-web with MIT License | 6 votes |
ToastContainer: React.FC<ToastContainerProps> = ({ messages }) => {
const messagesWithTransitions = useTransition(
messages,
message => message.id,
{
from: { right: '-120%', opacity: 0 },
enter: { right: '0%', opacity: 1 },
leave: { right: '-120%', opacity: 0 },
},
);
return (
<Container>
{messagesWithTransitions.map(({ item, key, props }) => (
<Toast key={key} message={item} style={props} />
))}
</Container>
);
}
Example #2
Source File: index.tsx From ecoleta with MIT License | 6 votes |
ToastContainer: React.FC<IToastContainerProps> = ({ messages }) => {
const messagesWithTransitions = useTransition(
messages,
message => message.id,
{
from: { right: '-120%', opacity: 0 },
enter: { right: '0%', opacity: 1 },
leave: { right: '-120%', opacity: 0 },
},
);
return (
<Container>
{messagesWithTransitions.map(({ item, key, props }) => (
<Toast key={key} message={item} style={props} />
))}
</Container>
);
}
Example #3
Source File: index.tsx From front-entenda-direito with GNU General Public License v3.0 | 6 votes |
ToastContainer: React.FC<ToastContainerProps> = ({ messages }) => {
const messagesWithTransitions = useTransition(
messages,
(message) => message.id,
{
from: { right: '-120%', opacity: 0, transform: 'rotateZ(0deg)' },
enter: { right: '0%', opacity: 1, transform: 'rotateZ(360deg)' },
leave: { right: '-120%', opacity: 0, transform: 'rotateZ(0deg)' },
},
);
return (
<Container>
{messagesWithTransitions.map(({ item, key, props }) => (
<Toast key={key} style={props} message={item} />
))}
</Container>
);
}
Example #4
Source File: index.tsx From front-entenda-direito with GNU General Public License v3.0 | 6 votes |
ToastContainerModal: React.FC<ToastContainerModalProps> = ({
messages,
}) => {
const messagesWithTransitions = useTransition(
messages,
(message) => message.id,
{
from: { right: '-120%', opacity: 0, transform: 'rotateZ(0deg)' },
enter: { right: '0%', opacity: 1, transform: 'rotateZ(360deg)' },
leave: { right: '-120%', opacity: 0, transform: 'rotateZ(0deg)' },
},
);
return (
<Container>
{messagesWithTransitions.map(({ item, key, props }) => (
<ToastModal key={key} style={props} message={item} />
))}
</Container>
);
}
Example #5
Source File: Routes.tsx From react-pokedex with MIT License | 6 votes |
Routes: React.FC = () => {
const location = useLocation();
const transitions = useTransition(location, (location) => location.pathname, {
config: {
duration: 250,
},
from: {
opacity: 0.25,
},
enter: {
opacity: 1,
},
leave: {
opacity: 0.25,
},
});
return (
<React.Suspense fallback={<SplashScreen />}>
{transitions.map(({ item: location, props, key }) => (
<animated.div
key={key}
style={{
...props,
width: "100%",
position: "absolute",
}}
>
<Switch location={location}>
<Route path="/pokemons/:id" component={PokemonDetailsPage} />
<Route exact path="/" component={PokemonsPage} />
</Switch>
</animated.div>
))}
</React.Suspense>
);
}
Example #6
Source File: index.tsx From cheeseswap-interface with GNU General Public License v3.0 | 6 votes |
export default function Modal({
isOpen,
onDismiss,
minHeight = false,
maxHeight = 50,
initialFocusRef,
children
}: ModalProps) {
const fadeTransition = useTransition(isOpen, null, {
config: { duration: 200 },
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 }
})
return (
<>
{fadeTransition.map(
({ item, key, props }) =>
item && (
<StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
<StyledDialogContent
aria-label="dialog content"
minHeight={minHeight}
maxHeight={maxHeight}
mobile={isMobile}
>
{/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
{!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
{children}
</StyledDialogContent>
</StyledDialogOverlay>
)
)}
</>
)
}
Example #7
Source File: index.tsx From rocketredis with MIT License | 6 votes |
ToastContainer: React.FC<ToastContainerProps> = ({ toasts }) => {
const visibleToasts = useMemo(() => {
if (toasts.length > 5) {
return toasts.slice(toasts.length - 5, toasts.length)
}
return toasts
}, [toasts])
const transitions = useTransition(visibleToasts, toast => toast.id, {
from: { right: '-120%' },
enter: { right: '0%' },
leave: { right: '-120%' },
config: {
duration: 200
}
})
return createPortal(
<Container>
{transitions.map(({ item, key, props }) => (
<Toast key={key} style={props} toast={item} />
))}
</Container>,
document.body
)
}
Example #8
Source File: index.tsx From panther-frontend-dex with GNU General Public License v3.0 | 6 votes |
export default function Modal({
isOpen,
onDismiss,
minHeight = false,
maxHeight = 50,
initialFocusRef,
children,
}: ModalProps) {
const fadeTransition = useTransition(isOpen, null, {
config: { duration: 200 },
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 },
})
return (
<>
{fadeTransition.map(
({ item, key, props }) =>
item && (
<StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
<StyledDialogContent
aria-label="dialog content"
minHeight={minHeight}
maxHeight={maxHeight}
mobile={isMobile}
>
{/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
{/* eslint-disable */}
{!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
{/* eslint-enable */}
{children}
</StyledDialogContent>
</StyledDialogOverlay>
)
)}
</>
)
}
Example #9
Source File: index.tsx From goose-frontend-amm with GNU General Public License v3.0 | 6 votes |
export default function Modal({
isOpen,
onDismiss,
minHeight = false,
maxHeight = 50,
initialFocusRef,
children,
}: ModalProps) {
const fadeTransition = useTransition(isOpen, null, {
config: { duration: 200 },
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 },
})
return (
<>
{fadeTransition.map(
({ item, key, props }) =>
item && (
<StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
<StyledDialogContent
aria-label="dialog content"
minHeight={minHeight}
maxHeight={maxHeight}
mobile={isMobile}
>
{/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
{/* eslint-disable */}
{!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
{/* eslint-enable */}
{children}
</StyledDialogContent>
</StyledDialogOverlay>
)
)}
</>
)
}
Example #10
Source File: index.tsx From vagasExplorer with MIT License | 6 votes |
ToastContainer: React.FC<ToastContainerProps> = ({ messages }) => {
const messagesWithTransitions = useTransition(
messages,
(message) => message.id,
{
from: { right: '-120%', opacity: 0 },
enter: { right: '0%', opacity: 1 },
leave: { right: '-120%', opacity: 0 },
},
);
return (
<Container>
{messagesWithTransitions.map(({ item, key, props }) => (
<Toast key={key} style={props} message={item} />
))}
</Container>
);
}
Example #11
Source File: SideDrawer.tsx From nyxo-website with MIT License | 6 votes |
SideDrawer: FC<Props> = ({ showMenu, toggleMenu }) => {
const handleClick = () => {
toggleMenu()
}
const transitions = useTransition(showMenu, null, {
from: { transform: "translateX(-100%)" },
enter: { transform: "translateX(0%)" },
leave: { transform: "translateX(-100%)" },
})
return (
<>
{transitions.map(({ item, key, props }) =>
item ? (
<SideDrawerWrap key={key} style={props}>
<Ul>
{links.map((link, index) => (
<Li key={index}>
<ClickLink
onClick={handleClick}
to={`/${link.path}`}
title={link.title}>
{link.title}
</ClickLink>
</Li>
))}
</Ul>
</SideDrawerWrap>
) : null
)}
</>
)
}
Example #12
Source File: index.tsx From gobarber-project with MIT License | 6 votes |
ToastContainer: React.FC<ToastContainerProps> = ({ messages }) => {
const messagesWithTransitions = useTransition(
messages,
message => message.id,
{
from: { right: '-120%', opacity: 0 },
enter: { right: '0%', opacity: 1 },
leave: { right: '-120%', opacity: 0 },
},
);
return (
<Container>
{messagesWithTransitions.map(({ item, key, props }) => (
<Toast key={key} style={props} message={item} />
))}
</Container>
);
}
Example #13
Source File: index.tsx From GoBarber with MIT License | 6 votes |
ToastContainer: React.FC<ToastContainerProps> = ({ messages }) => {
const messagesWithTransitions = useTransition(
messages,
(message) => message.id,
{
from: { right: '-120%', opacity: 0 },
enter: { right: '0%', opacity: 1 },
leave: { right: '-120%', opacity: 0 },
},
);
return (
<Container>
{messagesWithTransitions.map(({ item, key, props }) => (
<Toast key={key} style={props} message={item} />
))}
</Container>
);
}
Example #14
Source File: index.tsx From luaswap-interface with GNU General Public License v3.0 | 5 votes |
export default function Modal({
isOpen,
onDismiss = () => {},
minHeight = false,
maxHeight = 90,
initialFocusRef,
children
}: ModalProps) {
const fadeTransition = useTransition(isOpen, null, {
config: { duration: 200 },
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 }
})
const [{ y }, set] = useSpring(() => ({ y: 0, config: { mass: 1, tension: 210, friction: 20 } }))
const bind = useGesture({
onDrag: state => {
set({
y: state.down ? state.movement[1] : 0
})
if (state.movement[1] > 300 || (state.velocity > 3 && state.direction[1] > 0)) {
onDismiss()
}
}
})
return (
<>
{fadeTransition.map(
({ item, key, props }) =>
item && (
<StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
<StyledDialogContent
{...(isMobile
? {
...bind(),
style: { transform: y.interpolate(y => `translateY(${y > 0 ? y : 0}px)`) }
}
: {})}
aria-label="dialog content"
minHeight={minHeight}
maxHeight={maxHeight}
mobile={isMobile}
>
{/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
{!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
{children}
</StyledDialogContent>
</StyledDialogOverlay>
)
)}
</>
)
}
Example #15
Source File: index.tsx From sushiswap-exchange with GNU General Public License v3.0 | 5 votes |
export default function Modal({
isOpen,
onDismiss,
minHeight = false,
maxHeight = 50,
initialFocusRef,
children
}: ModalProps) {
const fadeTransition = useTransition(isOpen, null, {
config: { duration: 200 },
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 }
})
const [{ y }, set] = useSpring(() => ({ y: 0, config: { mass: 1, tension: 210, friction: 20 } }))
const bind = useGesture({
onDrag: state => {
set({
y: state.down ? state.movement[1] : 0
})
if (state.movement[1] > 300 || (state.velocity > 3 && state.direction[1] > 0)) {
onDismiss()
}
}
})
return (
<>
{fadeTransition.map(
({ item, key, props }) =>
item && (
<StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
<StyledDialogContent
{...(isMobile
? {
...bind(),
style: { transform: y.interpolate(y => `translateY(${y > 0 ? y : 0}px)`) }
}
: {})}
aria-label="dialog content"
minHeight={minHeight}
maxHeight={maxHeight}
mobile={isMobile}
>
{/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
{!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
{children}
</StyledDialogContent>
</StyledDialogOverlay>
)
)}
</>
)
}
Example #16
Source File: Skeleton.tsx From game-store-monorepo-app with MIT License | 5 votes |
Skeleton: React.FC<SkeletonProps> = ({ isLoading = true, theme, children }) => {
const transitions = useTransition(isLoading, {
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 },
delay: 200,
});
const renderContentLoader = () => {
switch (theme) {
case 'FACEBOOK':
return <Facebook />;
case 'INSTAGRAM':
return <Instagram />;
case 'CODE':
return <Code height={50} backgroundColor="#979797" foregroundColor="#aeaeae" />;
case 'LIST':
return <List />;
case 'BULLET_LIST':
return <BulletList />;
case 'GAME_LIST_ITEM':
return <GameListItemSkeleton />;
case 'GAME_CARD_ITEM':
return <GameCardItemSkeleton />;
case 'PROFILE_INFO_CARD':
return <ProfileInfoCardSkeleton />;
case 'TEXT':
return <TextSkeleton />;
default:
return null;
}
};
return transitions(({ opacity }, item) => {
return item ? (
<animated.div
style={{
opacity: opacity.to({ range: [0.0, 1.0], output: [0, 1] }),
}}
>
{renderContentLoader()}
</animated.div>
) : (
<animated.div
style={{
opacity: opacity.to({ range: [1.0, 0.0], output: [1, 0] }),
}}
>
{children}
</animated.div>
);
});
}
Example #17
Source File: useModalTransition.ts From react-simple-hook-modal with MIT License | 5 votes |
useModalTransition = (
transition: ModalTransition = ModalTransition.SCALE,
isOpen: boolean
) => {
return useTransition(isOpen, null, ModalTransitionConfig[transition]);
}
Example #18
Source File: index.tsx From limit-orders-lib with GNU General Public License v3.0 | 5 votes |
export default function Modal({
isOpen,
onDismiss,
minHeight = false,
maxHeight = 90,
initialFocusRef,
children,
}: ModalProps) {
const fadeTransition = useTransition(isOpen, null, {
config: { duration: 200 },
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 },
});
const [{ y }, set] = useSpring(() => ({
y: 0,
config: { mass: 1, tension: 210, friction: 20 },
}));
const bind = useGesture({
onDrag: (state) => {
set({
y: state.down ? state.movement[1] : 0,
});
if (
state.movement[1] > 300 ||
(state.velocity > 3 && state.direction[1] > 0)
) {
onDismiss();
}
},
});
return (
<Fragment>
{fadeTransition.map(
({ item, key, props }) =>
item && (
<StyledDialogOverlay
key={key}
style={props}
onDismiss={onDismiss}
initialFocusRef={initialFocusRef}
unstable_lockFocusAcrossFrames={false}
>
<StyledDialogContent
{...(isMobile
? {
...bind(),
style: {
transform: y.interpolate(
(y) => `translateY(${(y as number) > 0 ? y : 0}px)`
),
},
}
: {})}
aria-label="dialog content"
minHeight={minHeight}
maxHeight={maxHeight}
mobile={isMobile}
>
{/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
{!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
{children}
</StyledDialogContent>
</StyledDialogOverlay>
)
)}
</Fragment>
);
}
Example #19
Source File: index.tsx From dyp with Do What The F*ck You Want To Public License | 5 votes |
export default function Modal({
isOpen,
onDismiss,
minHeight = false,
maxHeight = 90,
initialFocusRef,
children
}: ModalProps) {
const fadeTransition = useTransition(isOpen, null, {
config: { duration: 200 },
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 }
})
const [{ y }, set] = useSpring(() => ({ y: 0, config: { mass: 1, tension: 210, friction: 20 } }))
const bind = useGesture({
onDrag: state => {
set({
y: state.down ? state.movement[1] : 0
})
if (state.movement[1] > 300 || (state.velocity > 3 && state.direction[1] > 0)) {
onDismiss()
}
}
})
return (
<>
{fadeTransition.map(
({ item, key, props }) =>
item && (
<StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
<StyledDialogContent
{...(isMobile
? {
...bind(),
style: { transform: y.interpolate(y => `translateY(${y > 0 ? y : 0}px)`) }
}
: {})}
aria-label="dialog content"
minHeight={minHeight}
maxHeight={maxHeight}
mobile={isMobile}
>
{/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
{!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
{children}
</StyledDialogContent>
</StyledDialogOverlay>
)
)}
</>
)
}
Example #20
Source File: index.tsx From sybil-interface with GNU General Public License v3.0 | 5 votes |
export default function Modal({
isOpen,
onDismiss,
minHeight = false,
maxHeight = 90,
initialFocusRef,
children,
}: ModalProps): JSX.Element {
const fadeTransition = useTransition(isOpen, null, {
config: { duration: 200 },
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 },
})
const [{ y }, set] = useSpring(() => ({ y: 0, config: { mass: 1, tension: 210, friction: 20 } }))
const bind = useGesture({
onDrag: (state) => {
set({
y: state.down ? state.movement[1] : 0,
})
if (state.movement[1] > 300 || (state.velocity > 3 && state.direction[1] > 0)) {
onDismiss()
}
},
})
return (
<>
{fadeTransition.map(
({ item, key, props }) =>
item && (
<StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
<StyledDialogContent
{...(isMobile
? {
...bind(),
style: { transform: y.interpolate((y: any) => `translateY(${y > 0 ? y : 0}px)`) },
}
: {})}
aria-label="dialog content"
minHeight={minHeight}
maxHeight={maxHeight}
mobile={isMobile}
>
{/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
{!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
{children}
</StyledDialogContent>
</StyledDialogOverlay>
)
)}
</>
)
}
Example #21
Source File: index.tsx From cuiswap with GNU General Public License v3.0 | 5 votes |
export default function Modal({
isOpen,
onDismiss,
minHeight = false,
maxHeight = 50,
initialFocusRef = null,
children
}: ModalProps) {
const fadeTransition = useTransition(isOpen, null, {
config: { duration: 200 },
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 }
})
const [{ y }, set] = useSpring(() => ({ y: 0, config: { mass: 1, tension: 210, friction: 20 } }))
const bind = useGesture({
onDrag: state => {
set({
y: state.down ? state.movement[1] : 0
})
if (state.movement[1] > 300 || (state.velocity > 3 && state.direction[1] > 0)) {
onDismiss()
}
}
})
return (
<>
{fadeTransition.map(
({ item, key, props }) =>
item && (
<StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
<StyledDialogContent
{...(isMobile
? {
...bind(),
style: { transform: y.interpolate(y => `translateY(${y > 0 ? y : 0}px)`) }
}
: {})}
aria-label="dialog content"
minHeight={minHeight}
maxHeight={maxHeight}
mobile={isMobile}
>
{/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
{!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
{children}
</StyledDialogContent>
</StyledDialogOverlay>
)
)}
</>
)
}
Example #22
Source File: PokemonDetailsPage.tsx From react-pokedex with MIT License | 4 votes |
PokemonDetailsPage = ({ match }: RouteComponentProps<MatchParams>) => {
const { id } = match.params;
const dispatch = useDispatch();
const history = useHistory();
const [activeTab, setActiveTab] = useState<PokemonTabs>("biography");
const transitions = useTransition(activeTab, (p) => p, {
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 },
config: {
duration: 250,
},
});
const pokemons = useSelector(pokemonsSelector);
const species = useSelector(speciesSelector);
const evolutionChain = useSelector(evolutionChainSelector);
const [chainLinks, setChainLinks] = useState<ChainLink[]>([]);
const [
selectedEvolutionPokemonIds,
setSelectedEvolutionPokemonIds,
] = useState<number[]>([]);
const selectedPokemon = pokemons.data.find(
(pokemon) => pokemon !== null && pokemon.id === Number(id)
);
const selectedSpecies = species.data.find((s) => s.id === Number(id));
const evolutionChainId =
selectedSpecies?.evolutionChain?.url.split("/").slice(-2)[0] || null;
const selectedEvolutionChain =
evolutionChainId !== null
? evolutionChain.data.find((e) => e.id === Number(evolutionChainId))
: null;
const getPokemonEvolution = useCallback(
(chain: ChainLink | null): ChainLink[] => {
if (!chain) {
return [];
} else {
return [chain].concat(getPokemonEvolution(chain.evolvesTo[0]));
}
},
[]
);
useEffect(() => {
if (selectedEvolutionChain?.chain) {
const pokemons: ChainLink[] = getPokemonEvolution(
selectedEvolutionChain.chain
);
const pokemonIds = pokemons.map(({ species }) =>
Number(species.url.split("/").slice(-2)[0])
);
dispatch(getPokemonsDynamically({ pokemonIds }));
setSelectedEvolutionPokemonIds(pokemonIds);
setChainLinks(pokemons);
}
//eslint-disable-next-line
}, [selectedEvolutionChain]);
useEffect(() => {
if (pokemons.data.length === 0) {
dispatch(getPokemonById({ pokemonId: id }));
}
dispatch(getSpeciesById({ pokemonId: id }));
//eslint-disable-next-line
}, [id, pokemons.data.length]);
useEffect(() => {
if (evolutionChainId) {
dispatch(getEvolutionChainById({ id: Number(evolutionChainId) }));
}
//eslint-disable-next-line
}, [selectedPokemon, evolutionChainId]);
const backgroundColors = selectedPokemon?.types.map(({ type }) => {
const [[, backgroundColor]] = Object.entries(PokemonTypeColors).filter(
([key, _]) => key === type.name
);
return backgroundColor;
});
const selectedBackgroundColor = backgroundColors && backgroundColors[0];
const isPageLoading =
species.status.state === SliceStatus.IDLE ||
species.status.state === SliceStatus.LOADING ||
evolutionChain.status.state === SliceStatus.IDLE ||
evolutionChain.status.state === SliceStatus.LOADING ||
pokemons.status.state === SliceStatus.IDLE ||
pokemons.status.state === SliceStatus.LOADING;
return (
<Layout title={capitalize(selectedPokemon?.name)}>
{isPageLoading ? (
<div className="text-center mx-auto mt-12">
<ScaleLoader color="#E3350D" radius={16} />
</div>
) : (
<>
<>
{selectedPokemon &&
selectedSpecies &&
selectedBackgroundColor &&
selectedEvolutionChain && (
<div className="pb-8">
<button
className="text-primary font-semibold transform hover:-translate-y-1 transition-transform ease-in duration-150 focus:outline-none"
onClick={() => history.push("/")}
>
<span className="text-primary font-semibold">Go Back</span>
</button>
<div
className="flex flex-col lg:flex-row justify-center items-start w-full mx-auto my-4 rounded-lg shadow-lg"
style={{
backgroundColor:
selectedBackgroundColor &&
selectedBackgroundColor.medium,
}}
>
<PokemonDetailsHeader
pokemon={selectedPokemon}
species={selectedSpecies}
selectedBackgroundColor={selectedBackgroundColor}
/>
<div className="bg-white lg:mt-0 rounded-t-3xl rounded-b-lg lg:rounded-t-none lg:rounded-b-none lg:rounded-r-lg overflow-hidden w-full pt-16 lg:pt-8 px-6 md:px-12 lg:px-24">
<div className="flex flex-row justify-between w-full">
<Tab
handleSelect={() => setActiveTab("biography")}
isSelected={activeTab === "biography"}
>
Biography
</Tab>
<Tab
handleSelect={() => setActiveTab("stats")}
isSelected={activeTab === "stats"}
>
Stats
</Tab>
<Tab
handleSelect={() => setActiveTab("evolutions")}
isSelected={activeTab === "evolutions"}
>
Evolutions
</Tab>
</div>
<div className="relative mt-8 lg:h-178">
{transitions.map(({ item, key, props }) => {
let page: JSX.Element = (
<PokemonDetailsBiography
species={selectedSpecies}
pokemon={selectedPokemon}
/>
);
switch (item) {
case "biography":
page = (
<PokemonDetailsBiography
species={selectedSpecies}
pokemon={selectedPokemon}
/>
);
break;
case "stats":
page = (
<PokemonDetailsStats
pokemon={selectedPokemon}
/>
);
break;
case "evolutions":
page = (
<PokemonDetailsEvolutions
selectedIds={selectedEvolutionPokemonIds}
chainLinks={chainLinks}
selectedBackgroundColor={
selectedBackgroundColor
}
/>
);
break;
default:
break;
}
return (
<animated.div
key={key}
style={{
...props,
position: "relative",
width: "100%",
height: "100%",
}}
>
{page}
</animated.div>
);
})}
</div>
</div>
</div>
</div>
)}
</>
</>
)}
</Layout>
);
}
Example #23
Source File: FileSelect.tsx From atlas with GNU General Public License v3.0 | 3 votes |
FileSelect: React.FC<FileSelectProps> = ({
onUploadFile,
fileType,
maxSize,
title,
paragraph,
thumbnailUrl,
onReAdjustThumbnail,
onDropRejected,
onError,
error,
isLoading,
}) => {
const selectedFileTransition = useTransition(isLoading, {
from: { opacity: 0, transform: 'scale(1.5)', x: '0%' },
enter: { opacity: 1, transform: 'scale(1)', x: '0%' },
leave: { opacity: 0, transform: 'scale(1)', x: '-200%' },
config: {
duration: 400,
easing: beazierEasing(0, 0, 0.58, 1),
},
})
const innerContainerTransition = useTransition(fileType, {
from: { x: '200%' },
enter: { x: '0%' },
leave: { x: '-200%' },
immediate: fileType === 'video',
config: {
duration: 400,
easing: beazierEasing(0, 0, 0.58, 1),
},
})
const onDropAccepted: DropzoneOptions['onDropAccepted'] = useCallback(
(acceptedFiles) => {
const [file] = acceptedFiles
onUploadFile(file)
},
[onUploadFile]
)
const { getRootProps, getInputProps, isDragAccept, isFileDialogActive, open, acceptedFiles } = useDropzone({
onDropAccepted,
onDropRejected,
maxFiles: 1,
multiple: false,
accept: fileType + '/*',
maxSize,
noClick: true,
noKeyboard: true,
})
const [openErrorDialog, closeErrorDialog] = useConfirmationModal()
useEffect(() => {
if (!error) {
return
}
openErrorDialog({
title: 'Unsupported file type selected',
description: error,
iconType: 'warning',
primaryButton: {
onClick: () => {
closeErrorDialog()
onError?.(null, fileType)
open()
},
text: 'Reselect file',
},
secondaryButton: {
text: 'Cancel',
onClick: () => {
onError?.(null, fileType)
closeErrorDialog()
},
},
})
}, [closeErrorDialog, error, fileType, onError, open, openErrorDialog])
const handleReAdjustThumbnail = (e: React.MouseEvent<HTMLImageElement, MouseEvent>) => {
e.stopPropagation()
onReAdjustThumbnail?.()
}
return (
<DragAndDropArea {...getRootProps()} isDragAccept={isDragAccept} isFileDialogActive={isFileDialogActive}>
<input {...getInputProps()} />
{selectedFileTransition(
(styles, item) =>
item && (
<SelectedFileInfo style={{ opacity: styles.opacity }}>
<SelectedFileInfoBackground />
<SelectedFileInfoInnerContainer style={{ transform: styles.transform, x: styles.x }}>
<SvgIllustrativeFileSelected />
<SelectedFileInfoHeading variant="t100">selected</SelectedFileInfoHeading>
{acceptedFiles.length !== 0 && <Text variant="t200">{acceptedFiles[0].name}</Text>}
</SelectedFileInfoInnerContainer>
</SelectedFileInfo>
)
)}
{innerContainerTransition((style, item) =>
thumbnailUrl && fileType === 'image' ? (
<Thumbnail
isLoading={isLoading}
src={thumbnailUrl}
alt="video thumbnail"
onClick={handleReAdjustThumbnail}
title="Click to readjust"
/>
) : (
<InnerContainer key={item} style={style} isLoading={isLoading}>
{fileType === 'video' ? <SvgIllustrativeVideo /> : <SvgIllustrativeImage />}
<Title variant="h400">{title}</Title>
<Paragraph variant="t200" as="p" secondary>
{paragraph}
</Paragraph>
<ButtonsGroup>
<DragDropText variant="t100" secondary>
Drag and drop or
</DragDropText>
<Button size="medium" onClick={() => open()} icon={<SvgActionUpload />}>
Select a file
</Button>
</ButtonsGroup>
</InnerContainer>
)
)}
</DragAndDropArea>
)
}