Skip to content

Commit 12db602

Browse files
authored
Merge pull request #2175 from mateuszbartosik/RDoc-3566
RDoc-3566 List out all the available icons in a template
2 parents 1cd1fca + 3a61e1a commit 12db602

File tree

5 files changed

+145
-6
lines changed

5 files changed

+145
-6
lines changed

scripts/generate-icon-types.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,21 @@ function generateIconTypes() {
99
const files = fs.readdirSync(ICONS_DIR);
1010
const svgFiles = files.filter((file) => file.endsWith(".svg"));
1111

12-
const iconNames = svgFiles.map((file) => {
12+
const iconNamesArray = svgFiles.map((file) => {
1313
const name = path.basename(file, ".svg");
14-
return ` | '${name}'`;
14+
return ` '${name}'`;
1515
});
1616

17-
const typesContent = `export type IconName =
18-
${iconNames.join("\n")};
17+
const typesContent = `
18+
export const ALL_ICON_NAMES = [
19+
${iconNamesArray.join(",\n")}
20+
] as const;
21+
22+
export type IconName = typeof ALL_ICON_NAMES[number];
1923
`;
2024

2125
fs.writeFileSync(TYPES_FILE, typesContent);
22-
console.log(`Generated icon types for ${svgFiles.length} icons:`);
26+
console.log(`Generated icon types for ${svgFiles.length} icons`);
2327
} catch (error) {
2428
console.error("Error generating icon types:", error);
2529
process.exit(1);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React, { useMemo } from "react";
2+
import IconGalleryCard from "./IconGalleryCard";
3+
import { ALL_ICON_NAMES } from "../../typescript/iconName";
4+
5+
export default function IconGallery() {
6+
const iconNames = useMemo(() => {
7+
return [...ALL_ICON_NAMES].sort();
8+
}, []);
9+
10+
return (
11+
<div className="icon-gallery mb-4">
12+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
13+
{iconNames.map((iconName) => (
14+
<IconGalleryCard key={iconName} iconName={iconName} />
15+
))}
16+
</div>
17+
</div>
18+
);
19+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React, { useState } from "react";
2+
import { Icon } from "../Common/Icon";
3+
import { IconName } from "@site/src/typescript/iconName";
4+
5+
export interface IconGalleryCardProps {
6+
iconName: IconName;
7+
}
8+
9+
export default function IconGalleryCard({ iconName }: IconGalleryCardProps) {
10+
const [copied, setCopied] = useState(false);
11+
12+
const handleCopy = async () => {
13+
try {
14+
await navigator.clipboard.writeText(iconName);
15+
setCopied(true);
16+
window.setTimeout(() => setCopied(false), 2000);
17+
} catch (err) {
18+
// eslint-disable-next-line no-console
19+
console.error("Failed to copy icon name to clipboard:", err);
20+
}
21+
};
22+
23+
return (
24+
<div
25+
className="group flex flex-col items-center justify-center p-4 rounded-lg border border-black/10 dark:border-white/10 bg-muted/40 hover:bg-muted/60 transition-all cursor-pointer"
26+
onClick={handleCopy}
27+
title={`Click to copy: ${iconName}`}
28+
>
29+
<div className="mb-3 flex items-center justify-center w-16 h-16">
30+
<Icon icon={iconName} size="lg" />
31+
</div>
32+
<div className="text-center">
33+
<div className="text-xs font-mono text-gray-700 dark:text-gray-300 break-all">
34+
{iconName}
35+
</div>
36+
<div className="text-xs text-gray-500 dark:text-gray-400 mt-1">
37+
{copied ? "Copied!" : "Click to copy"}
38+
</div>
39+
</div>
40+
</div>
41+
);
42+
}

static/icons/backup-history.svg

Lines changed: 1 addition & 1 deletion
Loading

templates/icon-gallery.mdx

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
title: "Icon Gallery"
3+
hide_table_of_contents: false
4+
sidebar_label: Icon Gallery
5+
---
6+
7+
import IconGallery from "@site/src/components/IconGallery/IconGallery";
8+
import Admonition from '@theme/Admonition';
9+
10+
# Icon Gallery
11+
12+
This page showcases all available icons in the project along with their names. Click on any icon to copy its name to the clipboard.
13+
14+
## Usage
15+
16+
To use an icon in a component, import the `Icon` component and pass the icon name as the `icon` prop:
17+
18+
```tsx
19+
import { Icon } from "@site/src/components/Common/Icon";
20+
21+
<Icon icon="database" size="lg" />
22+
```
23+
24+
## Available Icons
25+
26+
<IconGallery />
27+
28+
<Admonition type="info" title="">
29+
Icons are automatically loaded from the `static/icons` directory. When you add a new SVG file to this directory, the icon will automatically appear in this gallery after restarting the development server.
30+
</Admonition>
31+
32+
## Icon Sizes
33+
34+
The `Icon` component supports the following sizes:
35+
36+
- `xs` - 16x16px (w-4 h-4)
37+
- `sm` - 24x24px (w-6 h-6) - default
38+
- `md` - 32x32px (w-8 h-8)
39+
- `lg` - 40x40px (w-10 h-10)
40+
- `xl` - 48x48px (w-12 h-12)
41+
42+
## Usage Examples
43+
44+
### Basic Usage
45+
46+
```tsx
47+
import { Icon } from "@site/src/components/Common/Icon";
48+
49+
<Icon icon="database" />
50+
```
51+
52+
### With Custom Size
53+
54+
```tsx
55+
<Icon icon="database" size="xl" />
56+
```
57+
58+
### With Additional CSS Classes
59+
60+
```tsx
61+
<Icon icon="database" className="text-blue-500" />
62+
```
63+
64+
### In CardWithImage Component
65+
66+
```tsx
67+
import CardWithImage from "@site/src/components/Common/CardWithImage";
68+
69+
<CardWithImage
70+
title="Database"
71+
description="Database icon"
72+
imgIcon="database"
73+
/>
74+
```

0 commit comments

Comments
 (0)