diff --git a/docs/src/components/icon-grid.tsx b/docs/src/components/icon-grid.tsx new file mode 100644 index 00000000..0702c981 --- /dev/null +++ b/docs/src/components/icon-grid.tsx @@ -0,0 +1,103 @@ +import React from 'react'; +import iconsJson from '../../../dist/icons.json'; +import tagsJson from '../../../src/tags.json'; + +const icons = Object.entries(iconsJson).map(([name, svg]) => { + const tags: Array = tagsJson[name] || []; + return { name, svg, tags }; +}); + +export function IconGrid() { + const [query, setQuery] = React.useState(() => { + if (typeof window !== 'undefined') { + return new URLSearchParams(window.location.search).get('query') || ''; + } + + return ''; + }); + + const deferredQuery = React.useDeferredValue(query); + + // Sync the query to the URL + React.useEffect(() => { + if (typeof window !== 'undefined') { + const url = new URL(window.location.href); + + if (query) { + url.searchParams.set('query', query); + } else { + url.searchParams.delete('query'); + } + + window.history.replaceState({}, '', url.toString()); + } + }, [query]); + + const results = React.useMemo(() => { + if (!deferredQuery) { + return icons; + } + + return icons.filter(name => { + return ( + name.name.toLowerCase().includes(deferredQuery.toLowerCase()) || + name.tags.some(tag => + tag.toLowerCase().includes(deferredQuery.toLowerCase()), + ) + ); + }); + }, [deferredQuery]); + + const searchRef = React.useRef(null); + + React.useEffect(() => { + function handleKeydown(event: KeyboardEvent) { + if (!searchRef.current) return; + + if (event.key === '/') { + event.preventDefault(); + searchRef.current.focus(); + } + } + + console.log('adding event listener'); + + window.addEventListener('keydown', handleKeydown); + + return () => { + window.removeEventListener('keydown', handleKeydown); + }; + }, []); + + return ( +
+ setQuery(event.target.value)} + /> +
    + {results.map(icon => { + return ( +
  • + +
  • + ); + })} +
+
+ ); +} diff --git a/docs/src/index.css b/docs/src/index.css new file mode 100644 index 00000000..c5cab340 --- /dev/null +++ b/docs/src/index.css @@ -0,0 +1,17 @@ +:root { + color-scheme: light dark; + + --color-text: #000; + --color-bg: #fff; + --color-border: #ccc; + --color-border-focus: #0d99ff; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-text: #eeee; + --color-bg: #111; + --color-border: #333; + --color-border-focus: #0c8ce9; + } +} diff --git a/docs/src/pages/index.astro b/docs/src/pages/index.astro index 79af7354..46386831 100644 --- a/docs/src/pages/index.astro +++ b/docs/src/pages/index.astro @@ -1,31 +1,12 @@ --- -import icons from '../../../dist/icons.json'; +import '../index.css'; +import { IconGrid } from '../components/icon-grid'; --- - +
-
    - { - Object.entries(icons).map(([name, svg]) => { - return ( -
  • - -
  • - ); - }) - } -
+
diff --git a/docs/tailwind.config.cjs b/docs/tailwind.config.cjs index ba8cf3c3..8319b137 100644 --- a/docs/tailwind.config.cjs +++ b/docs/tailwind.config.cjs @@ -2,7 +2,14 @@ module.exports = { content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'], theme: { - extend: {}, + colors: { + transparent: 'transparent', + current: 'currentColor', + text: 'var(--color-text)', + bg: 'var(--color-bg)', + border: 'var(--color-border)', + 'border-focus': 'var(--color-border-focus)', + }, }, plugins: [], };