diff --git a/docs/.vitepress/lib/fetchAllContributors.ts b/docs/.vitepress/lib/fetchAllContributors.ts deleted file mode 100644 index e9518e030..000000000 --- a/docs/.vitepress/lib/fetchAllContributors.ts +++ /dev/null @@ -1,131 +0,0 @@ -import crypto from 'crypto'; -import fs from 'fs'; -import path from 'path'; -import { Contributor } from '../theme/types'; -import fetch, { Headers } from 'node-fetch' - -const IGNORE_COMMIT_MESSAGES = ['fork', 'optimize']; - -function getContentHashOfFile(path) { - return new Promise((resolve, reject) => { - const hash = crypto.createHash('sha256'); - const stream = fs.createReadStream(path); - stream.on('error', err => reject(err)); - stream.on('data', chunk => hash.update(chunk)); - stream.on('end', () => resolve(hash.digest('hex'))); - }); -} - -const fetchCommitsOfIcon = async (name) =>{ - try { - const headers = new Headers(); - const token = process.env.GITHUB_TOKEN; - const username = process.env.GITHUB_USERNAME; - const password = process.env.GITHUB_API_KEY; - headers.set( - 'Authorization', - token ? `Bearer ${token}` : `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`, - ); - - const res = await fetch( - `https://api.github.com/repos/lucide-icons/lucide/commits?path=icons/${name}.svg`, - { - method: 'GET', - headers, - }, - ); - - const data = await res.json(); - - return { - name, - commits: data, - }; - } catch (error) { - - throw new Error(error); - } - }; - -export const filterCommits = (commits) => - commits.filter(({ commit }) => - !IGNORE_COMMIT_MESSAGES.some(ignoreItem => - commit.message.toLowerCase().includes(ignoreItem), - )) - .map(({ author }) => ({ - author: author && author.login ? author.login : null, - })) - .filter(({ author }, index, self) => self.findIndex((commit) => commit.author === author) === index); - -const getIconHash = async (icon) => await getContentHashOfFile(path.join(process.cwd(), "../icons", `${icon}.svg`)) -const iconCacheDir = path.join(process.cwd(),'.vitepress/cache/github-api'); -const iconCache = (hash) => path.join(iconCacheDir, `${hash}.json`); - -export async function checkIconCache(icon) { - const hash = await getIconHash(icon); - - const cachePath = iconCache(hash); - - if(fs.existsSync( cachePath )) { - const iconCache = fs.readFileSync(cachePath, "utf8"); - - return JSON.parse(iconCache) - } - - return false -} - -async function writeIconCache(icon, content) { - const hash = await getIconHash(icon); - - const iconCachePath = iconCache(hash); - - if (!fs.existsSync(iconCacheDir)){ - fs.mkdirSync(iconCacheDir); -} - - fs.writeFileSync(iconCachePath, JSON.stringify(content), 'utf-8'); -} - -export async function getContributors(icon): Promise { - try { - let iconCommits - const iconCache = await checkIconCache(icon); - - if (iconCache) { - iconCommits = iconCache - } else { - const { commits } = await fetchCommitsOfIcon(icon); - - writeIconCache(icon, commits) - - iconCommits = commits - } - - if (iconCommits && iconCommits.length) { - return filterCommits(iconCommits); - } - - return []; - } catch (error) { - throw new Error(error); - } -} - -export async function getAllContributors(icons) { - try { - const AllIconCommits = await Promise.all(icons.map(fetchCommitsOfIcon)); - - const filteredCommits = AllIconCommits.reduce((acc, { name, commits }) => { - if (commits && commits.length) { - acc[name] = filterCommits(commits) - } - - return acc; - }, {}); - - return filteredCommits - } catch (error) { - console.error(error); - } -} diff --git a/docs/.vitepress/lib/icons.ts b/docs/.vitepress/lib/icons.ts index 67a3a5b46..b3ad51610 100644 --- a/docs/.vitepress/lib/icons.ts +++ b/docs/.vitepress/lib/icons.ts @@ -2,8 +2,7 @@ import fs from "fs"; import path from "path"; import { parseSync } from "svgson"; import { IconNode } from "../../../packages/lucide-react/src/createLucideIcon"; -import { IconEntity, Release } from "../theme/types"; -import { getContributors } from "./fetchAllContributors"; +import { IconEntity } from "../theme/types"; import { generateHashedKey } from "./helpers"; import releaseMeta from "../data/releaseMetaData.json"; @@ -26,7 +25,7 @@ export async function getData(name: string, { withChildKeys = false }: GetDataOp const svgContent = fs.readFileSync(svgPath, "utf8"); const jsonPath = path.join(directory, `${name}.json`); const jsonContent = fs.readFileSync(jsonPath, "utf8"); - const { tags, categories } = JSON.parse(jsonContent); + const { tags, categories, contributors } = JSON.parse(jsonContent); const iconNode = parseSync(svgContent).children.map( (child) => { @@ -40,14 +39,13 @@ export async function getData(name: string, { withChildKeys = false }: GetDataOp } ) as IconNode - // const contributors = await getContributors(name); - return { name, tags, categories, - // contributors, iconNode, + contributors, + // contributors: ['ericfennis', 'karsa-mistmere'], ...(releaseMeta[name] ?? {}) }; } diff --git a/docs/.vitepress/theme/components/PageContainer.vue b/docs/.vitepress/theme/components/PageContainer.vue index 9653851f6..2a4aa553e 100644 --- a/docs/.vitepress/theme/components/PageContainer.vue +++ b/docs/.vitepress/theme/components/PageContainer.vue @@ -6,6 +6,6 @@ diff --git a/docs/.vitepress/theme/components/icons/CopyCodeButton.vue b/docs/.vitepress/theme/components/icons/CopyCodeButton.vue index b627b15d4..a24d693c5 100644 --- a/docs/.vitepress/theme/components/icons/CopyCodeButton.vue +++ b/docs/.vitepress/theme/components/icons/CopyCodeButton.vue @@ -53,6 +53,28 @@ function copyVue() { navigator.clipboard.writeText(code) } +function copyAngular() { + let attrs = [''] + + attrs.push(`name="${props.name}"`) + + if (size.value && size.value !== 24) { + attrs.push(`[size]="${size.value}"`) + } + + if (color.value && color.value !== 'currentColor') { + attrs.push(`color="${color.value}"`) + } + + if (strokeWidth.value && strokeWidth.value !== 2) { + attrs.push(`[strokeWidth]="${strokeWidth.value}"`) + } + + const code = `` + + navigator.clipboard.writeText(code) +} + function confetti(e) { animate.value = true; @@ -72,6 +94,7 @@ function confetti(e) { { text: 'Copy JSX' , onClick: copyJSX }, { text: 'Copy Vue' , onClick: copyVue }, { text: 'Copy Svelte' , onClick: copyJSX }, + { text: 'Copy Angular' , onClick: copyAngular }, ]" /> diff --git a/docs/.vitepress/theme/components/icons/IconContributors.vue b/docs/.vitepress/theme/components/icons/IconContributors.vue new file mode 100644 index 000000000..fe47b1d11 --- /dev/null +++ b/docs/.vitepress/theme/components/icons/IconContributors.vue @@ -0,0 +1,78 @@ + + + + + diff --git a/docs/.vitepress/theme/components/icons/IconDetailName.vue b/docs/.vitepress/theme/components/icons/IconDetailName.vue index 8875a7897..67031a52f 100644 --- a/docs/.vitepress/theme/components/icons/IconDetailName.vue +++ b/docs/.vitepress/theme/components/icons/IconDetailName.vue @@ -9,7 +9,6 @@ font-size: 24px; font-weight: 500; line-height: 32px; - margin-bottom: 12px; transition: background ease-in .15s;; padding: 2px 8px; border-radius: 8px; diff --git a/docs/.vitepress/theme/components/icons/IconDetailOverlay.vue b/docs/.vitepress/theme/components/icons/IconDetailOverlay.vue index d1402c0f0..6fdcf9ee6 100644 --- a/docs/.vitepress/theme/components/icons/IconDetailOverlay.vue +++ b/docs/.vitepress/theme/components/icons/IconDetailOverlay.vue @@ -3,6 +3,7 @@ import { computed, ref } from 'vue' import createLucideIcon from 'lucide-vue-next/src/createLucideIcon'; import IconButton from '../base/IconButton.vue'; + import IconContributors from './IconContributors.vue'; import IconPreview from './IconPreview.vue'; import { x, expand } from '../../../data/iconNodes' import { useRouter } from 'vitepress'; @@ -47,7 +48,11 @@ :iconNode="props.icon.iconNode" customizable /> - + + + @@ -93,8 +98,8 @@ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); will-change: transform; pointer-events: all; - height: 240px; - padding: 24px 32px; + height: 288px; + padding: 24px; display: flex; box-shadow: var(--vp-shadow-5); } @@ -134,6 +139,4 @@ opacity: 0; } - - diff --git a/docs/.vitepress/theme/components/icons/IconInfo.vue b/docs/.vitepress/theme/components/icons/IconInfo.vue index ba928f3d1..3cea22774 100644 --- a/docs/.vitepress/theme/components/icons/IconInfo.vue +++ b/docs/.vitepress/theme/components/icons/IconInfo.vue @@ -40,7 +40,7 @@ const { page } = useData() - + @@ -51,8 +51,10 @@ const { page } = useData() gap: 8px; margin-bottom: 24px; } - .category { text-transform: capitalize; } +.icon-name { + margin-bottom: 12px; +} diff --git a/docs/.vitepress/theme/components/icons/IconsOverview.vue b/docs/.vitepress/theme/components/icons/IconsOverview.vue index 12bd94681..9b71a5acc 100644 --- a/docs/.vitepress/theme/components/icons/IconsOverview.vue +++ b/docs/.vitepress/theme/components/icons/IconsOverview.vue @@ -95,6 +95,6 @@ watch(searchQueryThrottled, (searchString) => { } .bottom-page { - height: 200px; + height: 288px; } diff --git a/docs/.vitepress/theme/types.ts b/docs/.vitepress/theme/types.ts index 79cbc3738..933512fd9 100644 --- a/docs/.vitepress/theme/types.ts +++ b/docs/.vitepress/theme/types.ts @@ -4,16 +4,12 @@ export interface IconEntity { name: string; tags: string[]; categories: string[]; - contributors: Contributor[]; + contributors: string[]; iconNode: IconNode; createdRelease?: Release; changedRelease?: Release; } -export interface Contributor { - author: string; -} - export interface Category { name: string title: string diff --git a/docs/icons/[name].md b/docs/icons/[name].md index d463b04bf..325f1e35d 100644 --- a/docs/icons/[name].md +++ b/docs/icons/[name].md @@ -12,7 +12,9 @@ import { computed } from 'vue' import { useData } from 'vitepress' import IconPreview from '../.vitepress/theme/components/icons/IconPreview.vue' import IconInfo from '../.vitepress/theme/components/icons/IconInfo.vue' +import IconContributors from '../.vitepress/theme/components/icons/IconContributors.vue' import CodeGroup from '../.vitepress/theme/components/base/CodeGroup.vue' +import Badge from '../.vitepress/theme/components/base/Badge.vue' import VPButton from 'vitepress/dist/client/theme-default/components/VPButton.vue'; import { data } from './codeExamples.data' import { camelCase, startCase } from 'lodash-es' @@ -50,6 +52,11 @@ const codeExample = computed(() => data.codeExamples?.map( /> +
+ Created: v{{$params.createdRelease.version}} + Last changed: v{{$params.changedRelease.version}} +
+ +