Bundle lucide-react as part of library

This commit is contained in:
Fuma Nama
2025-04-25 19:34:03 +08:00
parent 3eef0bdcee
commit 4e62b41001
20 changed files with 396 additions and 49 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'fumadocs-openapi': patch
'fumadocs-ui': patch
---
Bundle `lucide-react` as part of library
-1
View File
@@ -64,7 +64,6 @@
"github-slugger": "^2.0.0",
"hast-util-to-jsx-runtime": "^2.3.6",
"js-yaml": "^4.1.0",
"lucide-react": "^0.503.0",
"next-themes": "^0.4.6",
"openapi-sampler": "^1.6.1",
"react-hook-form": "^7.56.1",
+1
View File
@@ -0,0 +1 @@
export * from 'fumadocs-ui/internal/icons';
+2 -2
View File
@@ -44,7 +44,7 @@ import {
CollapsibleContent,
CollapsibleTrigger,
} from 'fumadocs-ui/components/ui/collapsible';
import { ChevronDown, Loader2 } from 'lucide-react';
import { ChevronDown, LoaderCircle } from 'lucide-react';
import type { Security } from '@/utils/get-security';
import {
OauthDialog,
@@ -263,7 +263,7 @@ export default function Client({
disabled={testQuery.isLoading}
>
{testQuery.isLoading ? (
<Loader2 className="size-4 animate-spin" />
<LoaderCircle className="size-4 animate-spin" />
) : (
'Send'
)}
@@ -1,4 +1,4 @@
import { CircleCheckIcon, CircleXIcon } from 'lucide-react';
import { CircleCheck, CircleX } from 'lucide-react';
interface StatusInfo {
description: string;
@@ -7,22 +7,22 @@ interface StatusInfo {
}
const statusMap: Record<number, StatusInfo> = {
400: { description: 'Bad Request', color: 'text-red-500', icon: CircleXIcon },
400: { description: 'Bad Request', color: 'text-red-500', icon: CircleX },
401: {
description: 'Unauthorized',
color: 'text-red-500',
icon: CircleXIcon,
icon: CircleX,
},
403: { description: 'Forbidden', color: 'text-red-500', icon: CircleXIcon },
403: { description: 'Forbidden', color: 'text-red-500', icon: CircleX },
404: {
description: 'Not Found',
color: 'text-fd-muted-foreground',
icon: CircleXIcon,
icon: CircleX,
},
500: {
description: 'Internal Server Error',
color: 'text-red-500',
icon: CircleXIcon,
icon: CircleX,
},
};
@@ -35,17 +35,17 @@ export function getStatusInfo(status: number): StatusInfo {
return {
description: 'Successful',
color: 'text-green-500',
icon: CircleCheckIcon,
icon: CircleCheck,
};
}
if (status >= 400) {
return { description: 'Error', color: 'text-red-500', icon: CircleXIcon };
return { description: 'Error', color: 'text-red-500', icon: CircleX };
}
return {
description: 'No Description',
color: 'text-fd-muted-foreground',
icon: CircleXIcon,
icon: CircleX,
};
}
+2 -1
View File
@@ -2,7 +2,8 @@
"extends": "tsconfig/react-library.json",
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
"@/*": ["./src/*"],
"lucide-react": ["./src/icons"]
}
},
"tsc-alias": {
+3 -3
View File
@@ -45,7 +45,8 @@
"eslint-config-custom": "workspace:*",
"fumadocs-core": "workspace:*",
"fumadocs-ui": "workspace:*",
"tsconfig": "workspace:*"
"tsconfig": "workspace:*",
"lucide-react": "^0.503.0"
},
"peerDependencies": {
"fumadocs-core": "15.x.x",
@@ -56,7 +57,6 @@
},
"dependencies": {
"class-variance-authority": "^0.7.1",
"js-yaml": "^4.1.0",
"lucide-react": "^0.503.0"
"js-yaml": "^4.1.0"
}
}
+4 -1
View File
@@ -61,6 +61,10 @@
"./utils/*": {
"import": "./dist/utils/*.js",
"types": "./dist/utils/*.d.ts"
},
"./internal/icons": {
"import": "./dist/icons.js",
"types": "./dist/icons.d.ts"
}
},
"files": [
@@ -90,7 +94,6 @@
"class-variance-authority": "^0.7.1",
"fumadocs-core": "workspace:*",
"lodash.merge": "^4.6.2",
"lucide-react": "^0.503.0",
"next-themes": "^0.4.6",
"postcss-selector-parser": "^7.1.0",
"react-medium-image-zoom": "^5.2.14",
+4 -4
View File
@@ -1,16 +1,16 @@
'use client';
import * as AccordionPrimitive from '@radix-ui/react-accordion';
import type {
AccordionMultipleProps,
AccordionSingleProps,
} from '@radix-ui/react-accordion';
import { Check, ChevronRight, LinkIcon } from 'lucide-react';
import * as AccordionPrimitive from '@radix-ui/react-accordion';
import { Check, ChevronRight, Link as LinkIcon } from 'lucide-react';
import {
forwardRef,
type ComponentPropsWithoutRef,
useState,
forwardRef,
useEffect,
useState,
} from 'react';
import { cn } from '@/utils/cn';
import { useCopyButton } from '@/utils/use-copy-button';
+2 -2
View File
@@ -1,4 +1,4 @@
import { AlertTriangle, CircleX, Info } from 'lucide-react';
import { CircleX, Info, TriangleAlert } from 'lucide-react';
import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';
import { cn } from '@/utils/cn';
import { cva } from 'class-variance-authority';
@@ -49,7 +49,7 @@ export const Callout = forwardRef<HTMLDivElement, CalloutProps>(
{
info: <Info className="size-5 fill-blue-500 text-fd-card" />,
warn: (
<AlertTriangle className="size-5 fill-orange-500 text-fd-card" />
<TriangleAlert className="size-5 fill-orange-500 text-fd-card" />
),
error: <CircleX className="size-5 fill-red-500 text-fd-card" />,
}[type]}
+13 -7
View File
@@ -1,14 +1,20 @@
'use client';
import { FileText, Hash, Loader2, SearchIcon, Text } from 'lucide-react';
import {
useMemo,
type ReactNode,
useEffect,
useState,
FileText,
Hash,
LoaderCircle,
Search as SearchIcon,
Text,
} from 'lucide-react';
import {
type ButtonHTMLAttributes,
useCallback,
type HTMLAttributes,
type ReactNode,
useCallback,
useEffect,
useMemo,
useState,
} from 'react';
import { useI18n } from '@/contexts/i18n';
import { cn } from '@/utils/cn';
@@ -221,7 +227,7 @@ function SearchResults({
function LoadingIndicator({ isLoading }: { isLoading: boolean }) {
return (
<div className="relative size-4">
<Loader2
<LoaderCircle
className={cn(
'absolute size-full animate-spin text-fd-primary transition-opacity',
!isLoading && 'opacity-0',
+6 -2
View File
@@ -1,8 +1,12 @@
'use client';
import { cva } from 'class-variance-authority';
import { FileIcon, FolderIcon, FolderOpen } from 'lucide-react';
import { useState, type HTMLAttributes, type ReactNode } from 'react';
import {
File as FileIcon,
Folder as FolderIcon,
FolderOpen,
} from 'lucide-react';
import { type HTMLAttributes, type ReactNode, useState } from 'react';
import { cn } from '@/utils/cn';
import {
Collapsible,
@@ -1,6 +1,6 @@
'use client';
import { type ButtonHTMLAttributes } from 'react';
import { SearchIcon } from 'lucide-react';
import { Search } from 'lucide-react';
import { useSearchContext } from '@/contexts/search';
import { useI18n } from '@/contexts/i18n';
import { cn } from '@/utils/cn';
@@ -34,7 +34,7 @@ export function SearchToggle({
setOpenSearch(true);
}}
>
<SearchIcon className="p-px" />
<Search className="p-px" />
</button>
);
}
@@ -62,7 +62,7 @@ export function LargeSearchToggle({
setOpenSearch(true);
}}
>
<SearchIcon className="ms-1 size-4" />
<Search className="ms-1 size-4" />
{text.search}
<div className="ms-auto inline-flex gap-0.5">
{hotKey.map((k, i) => (
+1 -1
View File
@@ -1,6 +1,6 @@
'use client';
import { InfoIcon } from 'lucide-react';
import { Info as InfoIcon } from 'lucide-react';
import Link from 'fumadocs-core/link';
import { cva } from 'class-variance-authority';
import { cn } from '@/utils/cn';
+332
View File
@@ -0,0 +1,332 @@
/**
* @license lucide-react - ISC
*
* All copyright belongs to https://github.com/lucide-icons/lucide, we bundle it as part of library to avoid upstream issues.
*/
import { type ComponentProps, createElement, forwardRef } from 'react';
import { cn } from '@/utils/cn';
const defaultAttributes: LucideProps = {
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',
};
type SVGElementType =
| 'circle'
| 'ellipse'
| 'g'
| 'line'
| 'path'
| 'polygon'
| 'polyline'
| 'rect';
export interface LucideProps extends ComponentProps<'svg'> {
size?: string | number;
}
export type IconNode = [
elementName: SVGElementType,
attrs: Record<string, string>,
][];
const createLucideIcon = (iconName: string, iconNode: IconNode) => {
const Component = forwardRef<SVGSVGElement, LucideProps>(
(
{ className, size = 24, color = 'currentColor', children, ...props },
ref,
) => {
return (
<svg
ref={ref}
{...defaultAttributes}
width={size}
height={size}
stroke={color}
className={cn('lucide', className)}
{...props}
>
{iconNode.map(([tag, attr]) => createElement(tag, attr))}
{children}
</svg>
);
},
);
Component.displayName = iconName;
return Component;
};
export const ChevronDown = createLucideIcon('chevron-down', [
['path', { d: 'm6 9 6 6 6-6', key: 'qrunsl' }],
]);
export const Languages = createLucideIcon('languages', [
['path', { d: 'm5 8 6 6', key: '1wu5hv' }],
['path', { d: 'm4 14 6-6 2-3', key: '1k1g8d' }],
['path', { d: 'M2 5h12', key: 'or177f' }],
['path', { d: 'M7 2h1', key: '1t2jsx' }],
['path', { d: 'm22 22-5-10-5 10', key: 'don7ne' }],
['path', { d: 'M14 18h6', key: '1m8k6r' }],
]);
export const Sidebar = createLucideIcon('panel-left', [
[
'rect',
{ width: '18', height: '18', x: '3', y: '3', rx: '2', key: 'afitv7' },
],
['path', { d: 'M9 3v18', key: 'fh3hqa' }],
]);
export const ChevronsUpDown = createLucideIcon('chevrons-up-down', [
['path', { d: 'm7 15 5 5 5-5', key: '1hf1tw' }],
['path', { d: 'm7 9 5-5 5 5', key: 'sgt6xg' }],
]);
export const Search = createLucideIcon('search', [
['circle', { cx: '11', cy: '11', r: '8', key: '4ej97u' }],
['path', { d: 'm21 21-4.3-4.3', key: '1qie3q' }],
]);
export const ExternalLink = createLucideIcon('external-link', [
['path', { d: 'M15 3h6v6', key: '1q9fwt' }],
['path', { d: 'M10 14 21 3', key: 'gplh6r' }],
[
'path',
{
d: 'M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6',
key: 'a6xqqp',
},
],
]);
export const Moon = createLucideIcon('moon', [
['path', { d: 'M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z', key: 'a7tn18' }],
]);
export const Sun = createLucideIcon('sun', [
['circle', { cx: '12', cy: '12', r: '4', key: '4exip2' }],
['path', { d: 'M12 2v2', key: 'tus03m' }],
['path', { d: 'M12 20v2', key: '1lh1kg' }],
['path', { d: 'm4.93 4.93 1.41 1.41', key: '149t6j' }],
['path', { d: 'm17.66 17.66 1.41 1.41', key: 'ptbguv' }],
['path', { d: 'M2 12h2', key: '1t8f8n' }],
['path', { d: 'M20 12h2', key: '1q8mjw' }],
['path', { d: 'm6.34 17.66-1.41 1.41', key: '1m8zz5' }],
['path', { d: 'm19.07 4.93-1.41 1.41', key: '1shlcs' }],
]);
export const Airplay = createLucideIcon('airplay', [
[
'path',
{
d: 'M5 17H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-1',
key: 'ns4c3b',
},
],
['path', { d: 'm12 15 5 6H7Z', key: '14qnn2' }],
]);
export const Menu = createLucideIcon('menu', [
['line', { x1: '4', x2: '20', y1: '12', y2: '12', key: '1e0a9i' }],
['line', { x1: '4', x2: '20', y1: '6', y2: '6', key: '1owob3' }],
['line', { x1: '4', x2: '20', y1: '18', y2: '18', key: 'yk5zj1' }],
]);
export const X = createLucideIcon('x', [
['path', { d: 'M18 6 6 18', key: '1bl5f8' }],
['path', { d: 'm6 6 12 12', key: 'd8bk6v' }],
]);
export const LoaderCircle = createLucideIcon('loader-circle', [
['path', { d: 'M21 12a9 9 0 1 1-6.219-8.56', key: '13zald' }],
]);
export const CircleCheck = createLucideIcon('circle-check', [
['circle', { cx: '12', cy: '12', r: '10', key: '1mglay' }],
['path', { d: 'm9 12 2 2 4-4', key: 'dzmm74' }],
]);
export const CircleX = createLucideIcon('circle-x', [
['circle', { cx: '12', cy: '12', r: '10', key: '1mglay' }],
['path', { d: 'm15 9-6 6', key: '1uzhvr' }],
['path', { d: 'm9 9 6 6', key: 'z0biqf' }],
]);
export const Check = createLucideIcon('check', [
['path', { d: 'M20 6 9 17l-5-5', key: '1gmf2c' }],
]);
export const TriangleAlert = createLucideIcon('triangle-alert', [
[
'path',
{
d: 'm21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3',
key: 'wmoenq',
},
],
['path', { d: 'M12 9v4', key: 'juzpu7' }],
['path', { d: 'M12 17h.01', key: 'p32p05' }],
]);
export const Info = createLucideIcon('info', [
['circle', { cx: '12', cy: '12', r: '10', key: '1mglay' }],
['path', { d: 'M12 16v-4', key: '1dtifu' }],
['path', { d: 'M12 8h.01', key: 'e9boi3' }],
]);
export const Copy = createLucideIcon('copy', [
[
'rect',
{
width: '14',
height: '14',
x: '8',
y: '8',
rx: '2',
ry: '2',
key: '17jyea',
},
],
[
'path',
{
d: 'M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2',
key: 'zix9uf',
},
],
]);
export const FileText = createLucideIcon('file-text', [
[
'path',
{
d: 'M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z',
key: '1rqfz7',
},
],
['path', { d: 'M14 2v4a2 2 0 0 0 2 2h4', key: 'tnqrlb' }],
['path', { d: 'M10 9H8', key: 'b1mrlr' }],
['path', { d: 'M16 13H8', key: 't4e002' }],
['path', { d: 'M16 17H8', key: 'z1uh3a' }],
]);
export const Hash = createLucideIcon('hash', [
['line', { x1: '4', x2: '20', y1: '9', y2: '9', key: '4lhtct' }],
['line', { x1: '4', x2: '20', y1: '15', y2: '15', key: 'vyu0kd' }],
['line', { x1: '10', x2: '8', y1: '3', y2: '21', key: '1ggp8o' }],
['line', { x1: '16', x2: '14', y1: '3', y2: '21', key: 'weycgp' }],
]);
export const Text = createLucideIcon('text', [
['path', { d: 'M15 18H3', key: 'olowqp' }],
['path', { d: 'M17 6H3', key: '16j9eg' }],
['path', { d: 'M21 12H3', key: '2avoz0' }],
]);
export const File = createLucideIcon('file', [
[
'path',
{
d: 'M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z',
key: '1rqfz7',
},
],
['path', { d: 'M14 2v4a2 2 0 0 0 2 2h4', key: 'tnqrlb' }],
]);
export const Folder = createLucideIcon('folder', [
[
'path',
{
d: 'M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z',
key: '1kt360',
},
],
]);
export const FolderOpen = createLucideIcon('folder-open', [
[
'path',
{
d: 'm6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2',
key: 'usdka0',
},
],
]);
export const Star = createLucideIcon('star', [
[
'path',
{
d: 'M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z',
key: 'r04s7s',
},
],
]);
export const Link = createLucideIcon('link', [
[
'path',
{
d: 'M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71',
key: '1cjeqo',
},
],
[
'path',
{
d: 'M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71',
key: '19qd67',
},
],
]);
export const Edit = createLucideIcon('square-pen', [
[
'path',
{
d: 'M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7',
key: '1m0v6g',
},
],
[
'path',
{
d: 'M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z',
key: 'ohrbg2',
},
],
]);
export const ChevronRight = createLucideIcon('chevron-right', [
['path', { d: 'm9 18 6-6-6-6', key: 'mthhwq' }],
]);
export const ChevronLeft = createLucideIcon('chevron-left', [
['path', { d: 'm15 18-6-6 6-6', key: '1wnfg3' }],
]);
export const Plus = createLucideIcon('plus', [
['path', { d: 'M5 12h14', key: '1ays0h' }],
['path', { d: 'M12 5v14', key: 's699le' }],
]);
export const Trash2 = createLucideIcon('trash-2', [
['path', { d: 'M3 6h18', key: 'd0wm0j' }],
['path', { d: 'M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6', key: '4alrt4' }],
['path', { d: 'M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2', key: 'v07s0e' }],
['line', { x1: '10', x2: '10', y1: '11', y2: '17', key: '1uufr5' }],
['line', { x1: '14', x2: '14', y1: '11', y2: '17', key: 'xtxkd' }],
]);
export const ChevronUp = createLucideIcon('chevron-up', [
['path', { d: 'm18 15-6-6-6 6', key: '153udz' }],
]);
+1 -1
View File
@@ -1,6 +1,6 @@
'use client';
import { Menu, SidebarIcon, X } from 'lucide-react';
import { Menu, Sidebar as SidebarIcon, X } from 'lucide-react';
import { type ButtonHTMLAttributes, type HTMLAttributes } from 'react';
import { cn } from '@/utils/cn';
import { buttonVariants } from '@/components/ui/button';
+1 -1
View File
@@ -1,6 +1,6 @@
import type { PageTree } from 'fumadocs-core/server';
import { type HTMLAttributes, type ReactNode, useMemo } from 'react';
import { Languages, SidebarIcon } from 'lucide-react';
import { Languages, Sidebar as SidebarIcon } from 'lucide-react';
import { cn } from '@/utils/cn';
import { buttonVariants } from '@/components/ui/button';
import {
+1 -1
View File
@@ -12,7 +12,7 @@ import {
import { TreeContextProvider } from '@/contexts/tree';
import { cn } from '@/utils/cn';
import { buttonVariants } from '@/components/ui/button';
import { ChevronDown, Languages, SidebarIcon } from 'lucide-react';
import { ChevronDown, Languages, Sidebar as SidebarIcon } from 'lucide-react';
import { BaseLinkItem, type LinkItemType } from '@/layouts/links';
import { LanguageToggle } from '@/components/layout/language-toggle';
import { ThemeToggle } from '@/components/layout/theme-toggle';
+2 -1
View File
@@ -2,7 +2,8 @@
"extends": "tsconfig/react-library.json",
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
"@/*": ["./src/*"],
"lucide-react": ["./src/icons"]
}
},
"tsc-alias": {
+3 -9
View File
@@ -1177,9 +1177,6 @@ importers:
js-yaml:
specifier: ^4.1.0
version: 4.1.0
lucide-react:
specifier: ^0.503.0
version: 0.503.0([email protected])
next-themes:
specifier: ^0.4.6
version: 0.4.6([email protected]([email protected]))([email protected])
@@ -1250,9 +1247,6 @@ importers:
js-yaml:
specifier: ^4.1.0
version: 4.1.0
lucide-react:
specifier: ^0.503.0
version: 0.503.0([email protected])
devDependencies:
'@types/js-yaml':
specifier: ^4.0.9
@@ -1272,6 +1266,9 @@ importers:
fumadocs-ui:
specifier: workspace:*
version: link:../ui
lucide-react:
specifier: ^0.503.0
version: 0.503.0([email protected])
tsconfig:
specifier: workspace:*
version: link:../tsconfig
@@ -1438,9 +1435,6 @@ importers:
lodash.merge:
specifier: ^4.6.2
version: 4.6.2
lucide-react:
specifier: ^0.503.0
version: 0.503.0([email protected])
next-themes:
specifier: ^0.4.6
version: 0.4.6([email protected]([email protected]))([email protected])