components: memoize and streamline callbacks
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { useCallback } from "react";
|
||||||
import { useRecoilState, useRecoilValue } from "recoil";
|
import { useRecoilState, useRecoilValue } from "recoil";
|
||||||
|
|
||||||
import { iconColorAtom } from "../../state/atoms";
|
import { iconColorAtom } from "../../state/atoms";
|
||||||
@@ -12,12 +12,15 @@ const ColorInput: React.FC<ColorInputProps> = () => {
|
|||||||
const [color, setColor] = useRecoilState(iconColorAtom);
|
const [color, setColor] = useRecoilState(iconColorAtom);
|
||||||
const isDark = useRecoilValue(isDarkThemeSelector);
|
const isDark = useRecoilValue(isDarkThemeSelector);
|
||||||
|
|
||||||
const handleColorChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleColorChange = useCallback(
|
||||||
const {
|
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
target: { value: color },
|
const {
|
||||||
} = event;
|
target: { value: color },
|
||||||
if (color[0] === "#") setColor(color);
|
} = event;
|
||||||
};
|
if (color[0] === "#") setColor(color);
|
||||||
|
},
|
||||||
|
[setColor]
|
||||||
|
);
|
||||||
|
|
||||||
const throttledColorChange = useThrottled(handleColorChange, 100, [
|
const throttledColorChange = useThrottled(handleColorChange, 100, [
|
||||||
handleColorChange,
|
handleColorChange,
|
||||||
|
|||||||
@@ -25,19 +25,17 @@ const illustrationVariants = {
|
|||||||
visible: { opacity: 1, transition: { duration: 0.2 } },
|
visible: { opacity: 1, transition: { duration: 0.2 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleGetStarted = () => {
|
const handleGetStarted = () =>
|
||||||
window.open(
|
window.open(
|
||||||
"https://github.com/phosphor-icons/phosphor-web#phosphor-icons",
|
"https://github.com/phosphor-icons/phosphor-web#phosphor-icons",
|
||||||
"_blank",
|
"_blank",
|
||||||
"noopener noreferrer"
|
"noopener noreferrer"
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const handleScrollToIcons = () => {
|
const handleScrollToIcons = () =>
|
||||||
document
|
document
|
||||||
.getElementById("toolbar")
|
.getElementById("toolbar")
|
||||||
?.scrollIntoView({ behavior: "smooth", block: "start" });
|
?.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||||
};
|
|
||||||
|
|
||||||
const Header: React.FC<HeaderProps> = () => {
|
const Header: React.FC<HeaderProps> = () => {
|
||||||
return (
|
return (
|
||||||
@@ -62,7 +60,11 @@ const Header: React.FC<HeaderProps> = () => {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="links">
|
<div className="links">
|
||||||
<a className="nav-link" href="#">
|
<a
|
||||||
|
className="nav-link"
|
||||||
|
href={`${process.env.PUBLIC_URL}/favicon.ico`}
|
||||||
|
download
|
||||||
|
>
|
||||||
Download all
|
Download all
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ interface IconGridItemProps extends IconProps {
|
|||||||
originOffset: MutableRefObject<{ top: number; left: number }>;
|
originOffset: MutableRefObject<{ top: number; left: number }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const whileTap = { boxShadow: "0 0 0 6px rgba(163, 159, 171, 0.1)" };
|
|
||||||
const transition = { duration: 0.2 };
|
const transition = { duration: 0.2 };
|
||||||
const originIndex = 0;
|
const originIndex = 0;
|
||||||
const delayPerPixel = 0.0004;
|
const delayPerPixel = 0.0004;
|
||||||
@@ -67,6 +66,7 @@ const IconGridItem: React.FC<IconGridItemProps> = (props) => {
|
|||||||
const d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
|
const d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
|
||||||
delayRef.current = d * delayPerPixel;
|
delayRef.current = d * delayPerPixel;
|
||||||
}, [originOffset]);
|
}, [originOffset]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ const SearchInput: React.FC<SearchInputProps> = () => {
|
|||||||
id="search-input"
|
id="search-input"
|
||||||
aria-label="Search for an icon"
|
aria-label="Search for an icon"
|
||||||
type="text"
|
type="text"
|
||||||
|
autoCapitalize="off"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
value={value}
|
value={value}
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ import "./SizeInput.css";
|
|||||||
type SizeInputProps = {};
|
type SizeInputProps = {};
|
||||||
|
|
||||||
const handleFocus = (event: React.UIEvent<HTMLInputElement>) => {
|
const handleFocus = (event: React.UIEvent<HTMLInputElement>) => {
|
||||||
const { currentTarget } = event;
|
event.preventDefault();
|
||||||
currentTarget.focus();
|
event.currentTarget.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlur = (event: React.UIEvent<HTMLInputElement>) => {
|
const handleBlur = (event: React.UIEvent<HTMLInputElement>) => {
|
||||||
|
event.preventDefault();
|
||||||
event.currentTarget.blur();
|
event.currentTarget.blur();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { useRecoilState } from "recoil";
|
import { useSetRecoilState } from "recoil";
|
||||||
import Select from "react-dropdown-select";
|
import Select from "react-dropdown-select";
|
||||||
import { PencilLine } from "phosphor-react";
|
import { PencilLine } from "phosphor-react";
|
||||||
|
|
||||||
@@ -7,7 +7,9 @@ import { iconStyleAtom } from "../../state/atoms";
|
|||||||
import { IconStyle } from "../../lib";
|
import { IconStyle } from "../../lib";
|
||||||
import "./StyleInput.css";
|
import "./StyleInput.css";
|
||||||
|
|
||||||
const options = [
|
type WeightOption = { key: string; value: IconStyle; icon: JSX.Element };
|
||||||
|
|
||||||
|
const options: WeightOption[] = [
|
||||||
{
|
{
|
||||||
key: "Thin",
|
key: "Thin",
|
||||||
value: IconStyle.THIN,
|
value: IconStyle.THIN,
|
||||||
@@ -43,12 +45,10 @@ const options = [
|
|||||||
type StyleInputProps = {};
|
type StyleInputProps = {};
|
||||||
|
|
||||||
const StyleInput: React.FC<StyleInputProps> = () => {
|
const StyleInput: React.FC<StyleInputProps> = () => {
|
||||||
const [style, setStyle] = useRecoilState(iconStyleAtom);
|
const setStyle = useSetRecoilState(iconStyleAtom);
|
||||||
void style;
|
|
||||||
|
|
||||||
// const handleStyleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
const handleStyleChange = (values: WeightOption[]) =>
|
||||||
// setStyle(event.target.value as IconStyle);
|
setStyle(values[0].value as IconStyle);
|
||||||
// };
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
@@ -56,7 +56,7 @@ const StyleInput: React.FC<StyleInputProps> = () => {
|
|||||||
values={[options[2]]}
|
values={[options[2]]}
|
||||||
searchable={false}
|
searchable={false}
|
||||||
labelField="key"
|
labelField="key"
|
||||||
onChange={(values) => setStyle(values[0].value as IconStyle)}
|
onChange={handleStyleChange}
|
||||||
itemRenderer={({
|
itemRenderer={({
|
||||||
item,
|
item,
|
||||||
itemIndex,
|
itemIndex,
|
||||||
|
|||||||
Reference in New Issue
Block a user