feat: Site (#1)
* site: pull data from "icons" dir * site: display icons * site: remove redundant code * site: colour mode support * site: header * site: order imports * site: search * site: add toast when copying icon * site: styling * site: hero * fix: disable theme toggle transitions * feat: Use Yarn Workspaces * refactor: Update site deploy scripts * refactor: Remove dark mode for now * feat: Add site title * refactor: Fix warning and format * feat: Add dark mode back 👀 * feat: Escape key to reset query * Fix by aelfric * Add Github link * Fix #40 Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
This commit is contained in:
32
packages/site/src/lib/icons.tsx
Normal file
32
packages/site/src/lib/icons.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import tags from '../../../../tags.json';
|
||||
|
||||
const directory = path.join(process.cwd(), "../../icons");
|
||||
|
||||
export function getAllNames() {
|
||||
const fileNames = fs.readdirSync(directory);
|
||||
|
||||
return fileNames.map((fileName) => {
|
||||
return fileName.replace(/\.svg$/, "");
|
||||
});
|
||||
}
|
||||
|
||||
export function getData(name) {
|
||||
const fullPath = path.join(directory, `${name}.svg`);
|
||||
const fileContents = fs.readFileSync(fullPath, "utf8");
|
||||
|
||||
return {
|
||||
name,
|
||||
tags: tags[name] || [],
|
||||
src: fileContents,
|
||||
};
|
||||
}
|
||||
|
||||
export function getAllData() {
|
||||
const names = getAllNames();
|
||||
|
||||
return names.map((name) => {
|
||||
return getData(name);
|
||||
});
|
||||
}
|
||||
34
packages/site/src/lib/key.js
Normal file
34
packages/site/src/lib/key.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const isCtrl = (e) => e.metaKey || e.ctrlKey;
|
||||
|
||||
// https://keycode.info
|
||||
export const useKeyBindings = (
|
||||
initialKeyBindings = {},
|
||||
eventListener = "keydown"
|
||||
) => {
|
||||
const [keyBindings] = useState(initialKeyBindings);
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener(
|
||||
eventListener,
|
||||
(event) => {
|
||||
const { code } = event;
|
||||
const keyBinding = keyBindings[code];
|
||||
if (keyBinding === undefined) return;
|
||||
const condition = keyBinding.ctrl ? isCtrl(event) : true;
|
||||
if (!condition) return;
|
||||
if (event.target.type != "text" || code == "Escape") {
|
||||
event.preventDefault();
|
||||
keyBinding.fn(event);
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
return () =>
|
||||
Object.keys(keyBindings).forEach((keyBinding) =>
|
||||
document.removeEventListener(eventListener, keyBindings[keyBinding])
|
||||
);
|
||||
}, []);
|
||||
};
|
||||
23
packages/site/src/lib/search.tsx
Normal file
23
packages/site/src/lib/search.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import Fuse from "fuse.js";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
function useSearch(icons, query) {
|
||||
const fuse = new Fuse(Object.values(icons), {
|
||||
threshold: 0.2,
|
||||
keys: ["name", "tags"],
|
||||
});
|
||||
|
||||
const [results, setResults] = useState(Object.values(icons));
|
||||
|
||||
useEffect(() => {
|
||||
if (query.trim()) {
|
||||
setResults(fuse.search(query.trim()));
|
||||
} else {
|
||||
setResults(Object.values(icons));
|
||||
}
|
||||
}, [query]);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
export default useSearch;
|
||||
74
packages/site/src/lib/theme.tsx
Normal file
74
packages/site/src/lib/theme.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
import { theme as chakraTheme } from "@chakra-ui/core";
|
||||
|
||||
const theme = {
|
||||
...chakraTheme,
|
||||
fonts: {
|
||||
...chakraTheme.fonts,
|
||||
body: `Jost,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"`,
|
||||
},
|
||||
icons: {
|
||||
...chakraTheme.icons,
|
||||
sun: {
|
||||
path: (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<circle cx="12" cy="12" r="5" />
|
||||
<line x1="12" y1="1" x2="12" y2="3" />
|
||||
<line x1="12" y1="21" x2="12" y2="23" />
|
||||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
|
||||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
|
||||
<line x1="1" y1="12" x2="3" y2="12" />
|
||||
<line x1="21" y1="12" x2="23" y2="12" />
|
||||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
|
||||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
moon: {
|
||||
path: (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
search: {
|
||||
path: (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<circle cx="11" cy="11" r="8" />
|
||||
<line x1="21" y1="21" x2="16.65" y2="16.65" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default theme;
|
||||
Reference in New Issue
Block a user