Add sample icons and refactor Icon interface
This commit is contained in:
@@ -8,13 +8,13 @@
|
|||||||
"@testing-library/user-event": "^7.1.2",
|
"@testing-library/user-event": "^7.1.2",
|
||||||
"@types/jest": "^24.0.0",
|
"@types/jest": "^24.0.0",
|
||||||
"@types/node": "^12.0.0",
|
"@types/node": "^12.0.0",
|
||||||
"@types/react": "^16.9.0",
|
"@types/react": "^16.9.43",
|
||||||
"@types/react-dom": "^16.9.0",
|
"@types/react-dom": "^16.9.8",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-scripts": "3.4.1",
|
"react-scripts": "3.4.1",
|
||||||
"recoil": "^0.0.10",
|
"recoil": "^0.0.10",
|
||||||
"typescript": "~3.7.2"
|
"typescript": "^3.9.6"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ const IconGrid: React.FC<IconGridProps> = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="grid">
|
<div className="grid">
|
||||||
{filteredQueryResults.map((icon) => (
|
{filteredQueryResults.map((icon) => (
|
||||||
<div key={`${icon.name}-${icon.style.type.toString()}`} className="grid-item">
|
<div key={`ph-${icon.name}-${icon.style}`} className="grid-item">
|
||||||
<img
|
<img
|
||||||
src="https://i.imgur.com/zaO12Y8m.jpeg"
|
src={icon.asset}
|
||||||
alt={`${icon.name} icon`}
|
alt={`${icon.name} icon`}
|
||||||
width="100%"
|
width="100%"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from "react";
|
|||||||
import { useRecoilState } from "recoil";
|
import { useRecoilState } from "recoil";
|
||||||
|
|
||||||
import { searchQueryAtom, styleQueryAtom } from "../../state/atoms";
|
import { searchQueryAtom, styleQueryAtom } from "../../state/atoms";
|
||||||
import { IconFillStyle } from "../../lib/Icon";
|
import { IconStyle } from "../../lib/Icon";
|
||||||
|
|
||||||
type IconSearchProps = {};
|
type IconSearchProps = {};
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ const IconSearch: React.FC<IconSearchProps> = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleStyleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
const handleStyleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
setStyle(event.target.value as IconFillStyle);
|
setStyle(event.target.value as IconStyle);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -23,9 +23,12 @@ const IconSearch: React.FC<IconSearchProps> = () => {
|
|||||||
<input value={query} onChange={handleSearchChange} />
|
<input value={query} onChange={handleSearchChange} />
|
||||||
<select value={style?.toString()} onChange={handleStyleChange}>
|
<select value={style?.toString()} onChange={handleStyleChange}>
|
||||||
<option value={""}>All</option>
|
<option value={""}>All</option>
|
||||||
<option value={IconFillStyle.LINE}>Line</option>
|
<option value={IconStyle.THIN}>Thin</option>
|
||||||
<option value={IconFillStyle.FILL}>Fill</option>
|
<option value={IconStyle.LIGHT}>Light</option>
|
||||||
<option value={IconFillStyle.DUOTONE}>Duotone</option>
|
<option value={IconStyle.REGULAR}>Regular</option>
|
||||||
|
<option value={IconStyle.BOLD}>Bold</option>
|
||||||
|
<option value={IconStyle.FILL}>Fill</option>
|
||||||
|
<option value={IconStyle.DUOTONE}>Duotone</option>
|
||||||
</select>
|
</select>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
import { Icon, IconCategory, IconFillStyle } from "../lib/Icon";
|
|
||||||
|
|
||||||
export const ICON_LIST: Icon[] = [
|
|
||||||
{
|
|
||||||
name: "arrow-up",
|
|
||||||
style: { type: IconFillStyle.LINE, weight: "light" },
|
|
||||||
categories: [
|
|
||||||
IconCategory.DESIGN,
|
|
||||||
IconCategory.EDITOR,
|
|
||||||
IconCategory.SYSTEM,
|
|
||||||
IconCategory.OTHER,
|
|
||||||
],
|
|
||||||
tags: ["point", "pointer", "direction"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "arrow-down",
|
|
||||||
style: { type: IconFillStyle.LINE, weight: "light" },
|
|
||||||
categories: [
|
|
||||||
IconCategory.DESIGN,
|
|
||||||
IconCategory.EDITOR,
|
|
||||||
IconCategory.SYSTEM,
|
|
||||||
IconCategory.OTHER,
|
|
||||||
],
|
|
||||||
tags: ["point", "pointer", "direction"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "arrow-left",
|
|
||||||
style: { type: IconFillStyle.LINE, weight: "light" },
|
|
||||||
categories: [
|
|
||||||
IconCategory.DESIGN,
|
|
||||||
IconCategory.EDITOR,
|
|
||||||
IconCategory.SYSTEM,
|
|
||||||
IconCategory.OTHER,
|
|
||||||
],
|
|
||||||
tags: ["point", "pointer", "direction"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "arrow-right",
|
|
||||||
style: { type: IconFillStyle.LINE, weight: "light" },
|
|
||||||
categories: [
|
|
||||||
IconCategory.DESIGN,
|
|
||||||
IconCategory.EDITOR,
|
|
||||||
IconCategory.SYSTEM,
|
|
||||||
IconCategory.OTHER,
|
|
||||||
],
|
|
||||||
tags: ["point", "pointer", "direction"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "house",
|
|
||||||
style: { type: IconFillStyle.FILL },
|
|
||||||
categories: [IconCategory.MAP, IconCategory.OTHER],
|
|
||||||
tags: ["building", "home", "place", "apartment"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "hospital",
|
|
||||||
style: { type: IconFillStyle.FILL },
|
|
||||||
categories: [IconCategory.MAP, IconCategory.HEALTH, IconCategory.OTHER],
|
|
||||||
tags: ["building", "doctor", "place", "treatment"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "mail",
|
|
||||||
style: { type: IconFillStyle.FILL },
|
|
||||||
categories: [IconCategory.BUSINESS, IconCategory.SYSTEM],
|
|
||||||
tags: ["email", "letter", "message", "messaging", "send"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "mail",
|
|
||||||
style: { type: IconFillStyle.DUOTONE },
|
|
||||||
categories: [
|
|
||||||
IconCategory.BUSINESS,
|
|
||||||
IconCategory.COMMUNICATION,
|
|
||||||
IconCategory.SYSTEM,
|
|
||||||
],
|
|
||||||
tags: ["email", "letter", "message", "messaging", "send"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "chat",
|
|
||||||
style: { type: IconFillStyle.DUOTONE },
|
|
||||||
categories: [IconCategory.COMMUNICATION, IconCategory.SYSTEM],
|
|
||||||
tags: ["message", "messaging", "send"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "chat",
|
|
||||||
style: { type: IconFillStyle.FILL },
|
|
||||||
categories: [IconCategory.COMMUNICATION, IconCategory.SYSTEM],
|
|
||||||
tags: ["message", "messaging", "send"],
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// name: "",
|
|
||||||
// style: IconFillStyle.FILL,
|
|
||||||
// categories: [],
|
|
||||||
// tags: [],
|
|
||||||
// },
|
|
||||||
];
|
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
export interface IconStyle {
|
export enum IconStyle {
|
||||||
type: IconFillStyle;
|
THIN = "thin",
|
||||||
weight?: "light" | "regular" | "medium" | "bold";
|
LIGHT = "light",
|
||||||
}
|
REGULAR = "regular",
|
||||||
|
BOLD = "bold",
|
||||||
export enum IconFillStyle {
|
|
||||||
LINE = "line",
|
|
||||||
FILL = "fill",
|
FILL = "fill",
|
||||||
DUOTONE = "duotone",
|
DUOTONE = "duotone",
|
||||||
}
|
}
|
||||||
@@ -20,7 +18,6 @@ export enum IconCategory {
|
|||||||
EDITOR = "Editor",
|
EDITOR = "Editor",
|
||||||
FINANCE = "Finance",
|
FINANCE = "Finance",
|
||||||
HEALTH = "Health & Medical",
|
HEALTH = "Health & Medical",
|
||||||
LOGOS = "Logos",
|
|
||||||
MAP = "Map",
|
MAP = "Map",
|
||||||
MEDIA = "Media",
|
MEDIA = "Media",
|
||||||
SYSTEM = "System",
|
SYSTEM = "System",
|
||||||
@@ -34,4 +31,5 @@ export interface Icon {
|
|||||||
style: IconStyle;
|
style: IconStyle;
|
||||||
categories: IconCategory[];
|
categories: IconCategory[];
|
||||||
tags: string[];
|
tags: string[];
|
||||||
|
asset: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { atom } from "recoil";
|
import { atom } from "recoil";
|
||||||
import { IconFillStyle } from "../lib/Icon";
|
import { IconStyle } from "../lib/Icon";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ATOM
|
* ATOM
|
||||||
@@ -8,14 +8,12 @@ import { IconFillStyle } from "../lib/Icon";
|
|||||||
* updates will result in a re-render of all components subscribed to that atom:
|
* updates will result in a re-render of all components subscribed to that atom:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export type IconStyleQuery = IconFillStyle | null | undefined;
|
|
||||||
|
|
||||||
export const searchQueryAtom = atom<string>({
|
export const searchQueryAtom = atom<string>({
|
||||||
key: "searchQueryAtom",
|
key: "searchQueryAtom",
|
||||||
default: "",
|
default: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const styleQueryAtom = atom<IconStyleQuery>({
|
export const styleQueryAtom = atom<IconStyle>({
|
||||||
key: "styleQueryAtom",
|
key: "styleQueryAtom",
|
||||||
default: undefined,
|
default: IconStyle.REGULAR,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { selector } from "recoil";
|
import { selector } from "recoil";
|
||||||
import { searchQueryAtom, styleQueryAtom, IconStyleQuery } from "./atoms";
|
import { searchQueryAtom, styleQueryAtom } from "./atoms";
|
||||||
import { ICON_LIST as list } from "../data/iconList";
|
import { iconList } from "../lib/iconList";
|
||||||
import { Icon } from "../lib/Icon";
|
import { Icon, IconStyle } from "../lib/Icon";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SELECTOR
|
* SELECTOR
|
||||||
@@ -14,16 +14,12 @@ const isQueryMatch = (icon: Icon, query: string): boolean => {
|
|||||||
return (
|
return (
|
||||||
icon.name.includes(query) ||
|
icon.name.includes(query) ||
|
||||||
icon.tags.some((tag) => tag.toLowerCase().includes(query)) ||
|
icon.tags.some((tag) => tag.toLowerCase().includes(query)) ||
|
||||||
icon.categories.some((category) =>
|
icon.categories.some((category) => category.toLowerCase().includes(query))
|
||||||
category.toLowerCase().includes(query)
|
|
||||||
) ||
|
|
||||||
icon.style.type.toString().includes(query) ||
|
|
||||||
!!icon.style.weight?.includes(query)
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const isStyleMatch = (icon: Icon, style: IconStyleQuery): boolean => {
|
const isStyleMatch = (icon: Icon, style?: IconStyle): boolean => {
|
||||||
return !style || icon.style.type === style;
|
return !style || icon.style === style;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const filteredQueryResultsSelector = selector({
|
export const filteredQueryResultsSelector = selector({
|
||||||
@@ -32,9 +28,9 @@ export const filteredQueryResultsSelector = selector({
|
|||||||
const query = get(searchQueryAtom).trim().toLowerCase();
|
const query = get(searchQueryAtom).trim().toLowerCase();
|
||||||
const style = get(styleQueryAtom);
|
const style = get(styleQueryAtom);
|
||||||
|
|
||||||
if (!query && !style) return list;
|
if (!query && !style) return iconList;
|
||||||
|
|
||||||
return list.filter((icon) => {
|
return iconList.filter((icon) => {
|
||||||
return isStyleMatch(icon, style) && isQueryMatch(icon, query);
|
return isStyleMatch(icon, style) && isQueryMatch(icon, query);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"incremental": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"noEmit": true
|
"noEmit": true
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user