mirror of
https://github.com/detleph/components.git
synced 2026-09-04 00:26:01 +02:00
Add tile component
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
@import "../../styles/highlight.scss";
|
||||
@import "../../styles/position.scss";
|
||||
@import "../../styles/colors.scss";
|
||||
|
||||
.tile {
|
||||
display: block;
|
||||
position: relative;
|
||||
|
||||
height: 8rem;
|
||||
width: 8rem;
|
||||
aspect-ratio: 1;
|
||||
font-size: 1.5rem;
|
||||
|
||||
display: grid;
|
||||
grid: 1fr 2.5rem / 1fr;
|
||||
|
||||
@include expand-bg();
|
||||
|
||||
text-decoration: none;
|
||||
|
||||
* {
|
||||
color: black;
|
||||
}
|
||||
|
||||
&:hover svg,
|
||||
&:focus-visible svg {
|
||||
fill: $accent;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 900px) {
|
||||
.tile {
|
||||
width: 10rem;
|
||||
height: 10rem;
|
||||
}
|
||||
}
|
||||
|
||||
.background {
|
||||
transition: transform 100ms;
|
||||
|
||||
position: absolute;
|
||||
@include fullInset();
|
||||
|
||||
@include highten;
|
||||
border-radius: 32px;
|
||||
}
|
||||
|
||||
.textContainer {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.iconContainer {
|
||||
height: 70%;
|
||||
width: 70%;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
aspect-ratio: 1;
|
||||
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
|
||||
* {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
svg {
|
||||
transition: fill 100ms;
|
||||
|
||||
fill: $unimportant;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from "react";
|
||||
import { ReactComponent } from "../../assets/svgr-custom";
|
||||
import styles from "./Tile.module.scss";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
interface TileProps {
|
||||
text: string;
|
||||
icon: typeof ReactComponent;
|
||||
|
||||
linkTo: string;
|
||||
|
||||
onClick?: () => unknown;
|
||||
}
|
||||
|
||||
const Tile: React.FC<TileProps> = ({ text, icon: Icon, linkTo, onClick }) => {
|
||||
return (
|
||||
<Link to={linkTo} onClick={onClick} className={styles.tile}>
|
||||
<div className={styles.background}></div>
|
||||
<span className={styles.iconContainer}>
|
||||
<Icon />
|
||||
</span>
|
||||
<span className={styles.textContainer}>{text}</span>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tile;
|
||||
@@ -0,0 +1,3 @@
|
||||
import Tile from "./Tile";
|
||||
|
||||
export default Tile;
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from "react";
|
||||
import { withRouter } from "storybook-addon-react-router-v6";
|
||||
// @ts-ignore
|
||||
import { ReactComponent as Icon } from "../assets/search.svg";
|
||||
|
||||
import { ComponentStory, ComponentMeta } from "@storybook/react";
|
||||
|
||||
import Tile from "../components/tile";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export default { title: "Tile", component: Tile, decorators: [withRouter] } as ComponentMeta<typeof Tile>;
|
||||
|
||||
const Template: ComponentStory<typeof Tile> = (args) => <Tile {...args} />;
|
||||
|
||||
export const defaultTile = Template.bind({});
|
||||
|
||||
defaultTile.args = {
|
||||
icon: Icon,
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
@mixin highten {
|
||||
border-radius: 32px;
|
||||
box-shadow: 0 6px 13px rgba($color: #000000, $alpha: 0.25);
|
||||
}
|
||||
|
||||
@mixin expand-bg($selector: ".background") {
|
||||
&:hover #{$selector},
|
||||
&:focus-visible #{$selector} {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
@mixin fullInset {
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
Reference in New Issue
Block a user