From 41159ceed2a1107ee4cdf79bd9d556822a050292 Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Sun, 23 Apr 2023 20:33:41 +0200 Subject: [PATCH] Add code examples --- docs/.gitignore | 3 +- docs/.vitepress/api/gh-icon/[...data].get.ts | 22 + docs/.vitepress/api/icon-nodes/index.get.ts | 28 + docs/.vitepress/api/icons/[iconName].get.ts | 46 + docs/.vitepress/api/tags/index.get.ts | 12 + docs/.vitepress/components/FakeInput.vue | 28 + .../components/HomeHeroIconsCard.data.ts | 2 +- .../components/HomeHeroIconsCard.vue | 94 +- docs/.vitepress/components/HomeInfo.vue | 5 - docs/.vitepress/components/IconButton.vue | 2 +- docs/.vitepress/components/IconDetail.vue | 53 + docs/.vitepress/components/IconDetailName.vue | 24 + .../components/IconDetailOverlay.vue | 54 +- docs/.vitepress/components/IconsOverview.vue | 18 +- docs/.vitepress/components/Input.vue | 17 +- .../composables/useIconCodeExample.ts | 192 ++++ docs/.vitepress/config.ts | 3 +- .../.vitepress/lib}/SvgPreview/index.tsx | 0 .../.vitepress/lib}/SvgPreview/types.ts | 0 .../.vitepress/lib}/SvgPreview/utils.ts | 0 docs/.vitepress/theme/style.css | 42 +- docs/.vitepress/vercel.json | 10 + docs/guide/installation.md | 32 +- docs/iconMetaData.ts | 936 ++++++++++++++++++ docs/icons/[name].md | 73 +- docs/icons/categories.md | 8 +- docs/index.md | 4 +- docs/license.md | 3 + docs/nitro.config.ts | 15 + docs/package.json | 15 +- docs/tsconfig.json | 6 +- docs/vercel.json | 2 +- pnpm-lock.yaml | 127 +-- scripts/writeIconMetaIndex.mjs | 29 + scripts/writeIconNodes.mjs | 40 + vercel.json | 10 + 36 files changed, 1802 insertions(+), 153 deletions(-) create mode 100644 docs/.vitepress/api/gh-icon/[...data].get.ts create mode 100644 docs/.vitepress/api/icon-nodes/index.get.ts create mode 100644 docs/.vitepress/api/icons/[iconName].get.ts create mode 100644 docs/.vitepress/api/tags/index.get.ts create mode 100644 docs/.vitepress/components/FakeInput.vue create mode 100644 docs/.vitepress/components/IconDetail.vue create mode 100644 docs/.vitepress/components/IconDetailName.vue create mode 100644 docs/.vitepress/composables/useIconCodeExample.ts rename {site/src/components => docs/.vitepress/lib}/SvgPreview/index.tsx (100%) rename {site/src/components => docs/.vitepress/lib}/SvgPreview/types.ts (100%) rename {site/src/components => docs/.vitepress/lib}/SvgPreview/utils.ts (100%) create mode 100644 docs/.vitepress/vercel.json create mode 100644 docs/iconMetaData.ts create mode 100644 docs/license.md create mode 100644 scripts/writeIconMetaIndex.mjs create mode 100644 scripts/writeIconNodes.mjs create mode 100644 vercel.json diff --git a/docs/.gitignore b/docs/.gitignore index d54d298b8..7d6794ba2 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -2,4 +2,5 @@ node_modules .vitepress/cache .vitepress/dist .vercel -.nitro \ No newline at end of file +.nitro +iconNodes diff --git a/docs/.vitepress/api/gh-icon/[...data].get.ts b/docs/.vitepress/api/gh-icon/[...data].get.ts new file mode 100644 index 000000000..bdd4af66d --- /dev/null +++ b/docs/.vitepress/api/gh-icon/[...data].get.ts @@ -0,0 +1,22 @@ +import { eventHandler, getQuery, setResponseHeader, defaultContentType } from 'h3' +import { renderToString } from 'react-dom/server' +import { createElement } from 'react' +import SvgPreview from '../../lib/SvgPreview/index.tsx'; + +export default eventHandler((event) => { + const { params } = event.context + + const [name, svgData] = params.data.split('/'); + const data = svgData.slice(0, -4); + + const src = Buffer.from(data, 'base64').toString('utf8'); + + const svg = Buffer.from( + renderToString(createElement(SvgPreview, {src, showGrid: true})) + ).toString('utf8'); + + defaultContentType(event, 'image/svg+xml') + setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000') + + return svg +}) diff --git a/docs/.vitepress/api/icon-nodes/index.get.ts b/docs/.vitepress/api/icon-nodes/index.get.ts new file mode 100644 index 000000000..ca4ad1c82 --- /dev/null +++ b/docs/.vitepress/api/icon-nodes/index.get.ts @@ -0,0 +1,28 @@ +import { eventHandler, getQuery, setResponseHeader } from 'h3' +import * as iconNodes from '../../../iconNodes' +import { kebabCase } from 'lodash-es' + +export default eventHandler((event) => { + const query = getQuery(event) + + const withUniqueKeys = query.withUniqueKeys === 'true' + + setResponseHeader(event, 'Cache-Control', 'public, max-age=86400') + + return Object.fromEntries( + Object.entries(iconNodes).map(([name, iconNode]) => { + const kebabName = kebabCase(name) + + if (withUniqueKeys) { + return [kebabName, iconNode] + } + + return [ + kebabName, + iconNode.map(([name, attrs]) => { + delete attrs.key + return [name, attrs] + })] + }) + ) +}) diff --git a/docs/.vitepress/api/icons/[iconName].get.ts b/docs/.vitepress/api/icons/[iconName].get.ts new file mode 100644 index 000000000..ba588436e --- /dev/null +++ b/docs/.vitepress/api/icons/[iconName].get.ts @@ -0,0 +1,46 @@ +import { eventHandler, getQuery, setResponseHeader, createError } from 'h3' +import * as iconNodes from '../../../iconNodes' +import { camelCase } from 'lodash-es' +import createLucideIcon from 'lucide-react/src/createLucideIcon' +import { renderToString } from 'react-dom/server' +import { createElement } from 'react' + +export default eventHandler((event) => { + const { params } = event.context + + const camelCaseName = camelCase(params.iconName) + const iconNode = iconNodes[camelCaseName] + + if (iconNode == null) { + const error = createError({ + statusCode: 404, + message: `Icon "${params.iconName}" not found`, + }) + + return sendError(event, error) + } + + const width = getQuery(event).width || undefined + const height = getQuery(event).height || undefined + const color = getQuery(event).color || undefined + const strokeWidth = getQuery(event).strokeWidth || undefined + + const LucideIcon = createLucideIcon(params.iconName, iconNode) + + const svg = Buffer.from( + renderToString( + createElement(LucideIcon, { + width, + height, + color: color ? `#${color}` : undefined, + strokeWidth, + } + )) + ).toString('utf8'); + + defaultContentType(event, 'image/svg+xml') + setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000') + + return svg + +}) diff --git a/docs/.vitepress/api/tags/index.get.ts b/docs/.vitepress/api/tags/index.get.ts new file mode 100644 index 000000000..91a911e26 --- /dev/null +++ b/docs/.vitepress/api/tags/index.get.ts @@ -0,0 +1,12 @@ +import { eventHandler, getQuery, setResponseHeader } from 'h3' +import * as iconMetaData from '../../../iconMetaData' +import { kebabCase } from 'lodash-es' + + +export default eventHandler((event) => { + setResponseHeader(event, 'Cache-Control', 'public, max-age=86400') + + return Object.fromEntries( + Object.entries(iconMetaData).map(([name, { tags }]) => [ kebabCase(name), tags ]) + ) +}) diff --git a/docs/.vitepress/components/FakeInput.vue b/docs/.vitepress/components/FakeInput.vue new file mode 100644 index 000000000..187f876bf --- /dev/null +++ b/docs/.vitepress/components/FakeInput.vue @@ -0,0 +1,28 @@ + + + + + diff --git a/docs/.vitepress/components/HomeHeroIconsCard.data.ts b/docs/.vitepress/components/HomeHeroIconsCard.data.ts index 76ca751bc..a58a38ba2 100644 --- a/docs/.vitepress/components/HomeHeroIconsCard.data.ts +++ b/docs/.vitepress/components/HomeHeroIconsCard.data.ts @@ -6,7 +6,7 @@ export default { async load() { const icons = await getAllData() - const randomIcons = Array.from({ length: 100 }, () => getRandomItem(icons)) + const randomIcons = Array.from({ length: 200 }, () => getRandomItem(icons)) return { icons: randomIcons, diff --git a/docs/.vitepress/components/HomeHeroIconsCard.vue b/docs/.vitepress/components/HomeHeroIconsCard.vue index b9958b941..87c726c56 100644 --- a/docs/.vitepress/components/HomeHeroIconsCard.vue +++ b/docs/.vitepress/components/HomeHeroIconsCard.vue @@ -1,47 +1,92 @@ diff --git a/docs/.vitepress/components/HomeInfo.vue b/docs/.vitepress/components/HomeInfo.vue index 0e8926d4f..0dd2c5ea8 100644 --- a/docs/.vitepress/components/HomeInfo.vue +++ b/docs/.vitepress/components/HomeInfo.vue @@ -23,9 +23,4 @@ } - - - - - diff --git a/docs/.vitepress/components/IconButton.vue b/docs/.vitepress/components/IconButton.vue index 98ff8f096..d63751f6e 100644 --- a/docs/.vitepress/components/IconButton.vue +++ b/docs/.vitepress/components/IconButton.vue @@ -1,5 +1,5 @@ diff --git a/docs/.vitepress/components/IconDetail.vue b/docs/.vitepress/components/IconDetail.vue new file mode 100644 index 000000000..1e35910c3 --- /dev/null +++ b/docs/.vitepress/components/IconDetail.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/docs/.vitepress/components/IconDetailName.vue b/docs/.vitepress/components/IconDetailName.vue new file mode 100644 index 000000000..8875a7897 --- /dev/null +++ b/docs/.vitepress/components/IconDetailName.vue @@ -0,0 +1,24 @@ + + + diff --git a/docs/.vitepress/components/IconDetailOverlay.vue b/docs/.vitepress/components/IconDetailOverlay.vue index ad747def9..39dcaa8f3 100644 --- a/docs/.vitepress/components/IconDetailOverlay.vue +++ b/docs/.vitepress/components/IconDetailOverlay.vue @@ -1,9 +1,12 @@