feat(client): shinny new landing page 🎉 (#39400)
Co-authored-by: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com> Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
@@ -15,7 +15,7 @@ function CurrentChallengeLink({ children, isLargeBtn }) {
|
||||
if (isLargeBtn) {
|
||||
classNames = 'btn btn-lg btn-primary btn-block';
|
||||
} else {
|
||||
classNames = 'btn btn-cta-big btn-primary btn-block';
|
||||
classNames = 'btn btn-primary btn-block';
|
||||
}
|
||||
return (
|
||||
<a className={classNames} href={`${apiLocation}${currentChallengeApi}`}>
|
||||
|
65
client/src/components/helpers/ImageLoader.js
Normal file
65
client/src/components/helpers/ImageLoader.js
Normal file
@@ -0,0 +1,65 @@
|
||||
import React from 'react';
|
||||
|
||||
import './image-loader.css';
|
||||
import LazyLoad from 'react-lazy-load';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const propTypes = {
|
||||
alt: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
height: PropTypes.number,
|
||||
loadedClassName: PropTypes.string,
|
||||
loadingClassName: PropTypes.string,
|
||||
src: PropTypes.string,
|
||||
width: PropTypes.number
|
||||
};
|
||||
|
||||
class ImageLoader extends React.Component {
|
||||
// initial state: image loaded stage
|
||||
state = {
|
||||
loaded: false
|
||||
};
|
||||
|
||||
// define our loading and loaded image classes
|
||||
static defaultProps = {
|
||||
className: '',
|
||||
loadingClassName: 'img-loading',
|
||||
loadedClassName: 'img-loaded'
|
||||
};
|
||||
|
||||
// image onLoad handler to update state to loaded
|
||||
onLoad = () => {
|
||||
this.setState(() => ({ loaded: true }));
|
||||
};
|
||||
|
||||
render() {
|
||||
let {
|
||||
className,
|
||||
loadedClassName,
|
||||
loadingClassName,
|
||||
alt,
|
||||
src,
|
||||
width,
|
||||
height
|
||||
} = this.props;
|
||||
|
||||
className = `${className} ${
|
||||
this.state.loaded ? loadedClassName : loadingClassName
|
||||
}`;
|
||||
|
||||
return (
|
||||
<LazyLoad
|
||||
debounce={false}
|
||||
height={height}
|
||||
offsetVertical={100}
|
||||
width={width}
|
||||
>
|
||||
{/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */}
|
||||
<img alt={alt} className={className} onLoad={this.onLoad} src={src} />
|
||||
{/* eslint-enable jsx-a11y/no-noninteractive-element-interactions */}
|
||||
</LazyLoad>
|
||||
);
|
||||
}
|
||||
}
|
||||
ImageLoader.propTypes = propTypes;
|
||||
export default ImageLoader;
|
23
client/src/components/helpers/image-loader.css
Normal file
23
client/src/components/helpers/image-loader.css
Normal file
@@ -0,0 +1,23 @@
|
||||
@keyframes fadeInImg {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.img-loading {
|
||||
opacity: 0;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.img-loaded {
|
||||
animation: fadeInImg cubic-bezier(0.23, 1, 0.32, 1) 1;
|
||||
position: relative;
|
||||
opacity: 0;
|
||||
animation-fill-mode: forwards;
|
||||
animation-duration: 0.7s;
|
||||
animation-delay: 0.1s;
|
||||
}
|
@@ -6,3 +6,4 @@ export { default as SkeletonSprite } from './SkeletonSprite';
|
||||
export { default as Spacer } from './Spacer';
|
||||
export { default as Link } from './Link';
|
||||
export { default as CurrentChallengeLink } from './CurrentChallengeLink';
|
||||
export { default as ImageLoader } from './ImageLoader';
|
||||
|
Reference in New Issue
Block a user