IconGrid: extract empty state into Warn component
The empty state now renders a Warn component, which can be used to show empty queries, or to show an arbitrary error message.
This commit is contained in:
@@ -2,19 +2,15 @@ import React, { useRef, useEffect } from "react";
|
|||||||
import { useRecoilValue } from "recoil";
|
import { useRecoilValue } from "recoil";
|
||||||
import { motion, useAnimation } from "framer-motion";
|
import { motion, useAnimation } from "framer-motion";
|
||||||
import { useWindowSize } from "react-use";
|
import { useWindowSize } from "react-use";
|
||||||
import { IconContext, Warning } from "phosphor-react";
|
import { IconContext } from "phosphor-react";
|
||||||
|
|
||||||
import {
|
import { iconStyleAtom, iconSizeAtom, iconColorAtom } from "../../state/atoms";
|
||||||
iconStyleAtom,
|
|
||||||
iconSizeAtom,
|
|
||||||
iconColorAtom,
|
|
||||||
searchQueryAtom,
|
|
||||||
} from "../../state/atoms";
|
|
||||||
import {
|
import {
|
||||||
filteredQueryResultsSelector,
|
filteredQueryResultsSelector,
|
||||||
isDarkThemeSelector,
|
isDarkThemeSelector,
|
||||||
} from "../../state/selectors";
|
} from "../../state/selectors";
|
||||||
import GridItem from "./IconGridItem";
|
import GridItem from "./IconGridItem";
|
||||||
|
import Warn from "../Warn/Warn";
|
||||||
import "./IconGrid.css";
|
import "./IconGrid.css";
|
||||||
|
|
||||||
type IconGridProps = {};
|
type IconGridProps = {};
|
||||||
@@ -23,7 +19,6 @@ const IconGrid: React.FC<IconGridProps> = () => {
|
|||||||
const weight = useRecoilValue(iconStyleAtom);
|
const weight = useRecoilValue(iconStyleAtom);
|
||||||
const size = useRecoilValue(iconSizeAtom);
|
const size = useRecoilValue(iconSizeAtom);
|
||||||
const color = useRecoilValue(iconColorAtom);
|
const color = useRecoilValue(iconColorAtom);
|
||||||
const query = useRecoilValue(searchQueryAtom);
|
|
||||||
const isDark = useRecoilValue(isDarkThemeSelector);
|
const isDark = useRecoilValue(isDarkThemeSelector);
|
||||||
|
|
||||||
const { width } = useWindowSize();
|
const { width } = useWindowSize();
|
||||||
@@ -38,22 +33,7 @@ const IconGrid: React.FC<IconGridProps> = () => {
|
|||||||
controls.start("visible");
|
controls.start("visible");
|
||||||
}, [controls, filteredQueryResults]);
|
}, [controls, filteredQueryResults]);
|
||||||
|
|
||||||
if (!filteredQueryResults.length)
|
if (!filteredQueryResults.length) return <Warn />;
|
||||||
return (
|
|
||||||
<div style={isDark ? { backgroundColor: "#35313D", color: "white" } : {}}>
|
|
||||||
<motion.div
|
|
||||||
className="empty-list"
|
|
||||||
initial={{ opacity: 0 }}
|
|
||||||
animate={{ opacity: 1 }}
|
|
||||||
transition={{ duration: 0.5 }}
|
|
||||||
>
|
|
||||||
<Warning size={128} color="currentColor" weight="fill" />
|
|
||||||
<p>
|
|
||||||
No results for '<code>{query}</code>'
|
|
||||||
</p>
|
|
||||||
</motion.div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IconContext.Provider value={{ weight, size, color, mirrored: false }}>
|
<IconContext.Provider value={{ weight, size, color, mirrored: false }}>
|
||||||
|
|||||||
36
src/components/Warn/Warn.tsx
Normal file
36
src/components/Warn/Warn.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { motion } from "framer-motion";
|
||||||
|
import { useRecoilValue } from "recoil";
|
||||||
|
|
||||||
|
import { isDarkThemeSelector } from "../../state/selectors";
|
||||||
|
import { searchQueryAtom } from "../../state/atoms";
|
||||||
|
import { Warning } from "phosphor-react";
|
||||||
|
|
||||||
|
interface WarnProps {
|
||||||
|
message?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Warn: React.FC<WarnProps> = ({ message }) => {
|
||||||
|
const isDark = useRecoilValue(isDarkThemeSelector);
|
||||||
|
const query = useRecoilValue(searchQueryAtom);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={isDark ? { backgroundColor: "#35313D", color: "white" } : {}}>
|
||||||
|
<motion.div
|
||||||
|
className="empty-list"
|
||||||
|
initial={{ opacity: 0 }}
|
||||||
|
animate={{ opacity: 1 }}
|
||||||
|
transition={{ duration: 0.5 }}
|
||||||
|
>
|
||||||
|
<Warning size={128} color="currentColor" weight="fill" />
|
||||||
|
{message ?? (
|
||||||
|
<p>
|
||||||
|
No results for '<code>{query}</code>'
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Warn;
|
||||||
Reference in New Issue
Block a user