This commit is contained in:
Tickbase
2025-05-18 16:09:24 +02:00
parent 07384e30cc
commit 4b70cec6e9
62 changed files with 3597 additions and 211 deletions

128
docs/adding-icons.md Normal file
View File

@@ -0,0 +1,128 @@
# Adding New Icons to Creamlinux
This guide explains how to add new icons to the Creamlinux project.
## Prerequisites
- Basic knowledge of SVG files
- Node.js and npm installed
- Creamlinux project set up
## Step 1: Find or Create SVG Icons
You can:
- Create your own SVG icons using tools like Figma, Sketch, or Illustrator
- Download icons from libraries like Heroicons, Material Icons, or Feather Icons
- Use existing SVG files
Ideally, icons should:
- Be 24x24px or have a viewBox of "0 0 24 24"
- Have a consistent style with existing icons
- Use stroke-width of 2 for outline variants
- Use solid fills for bold variants
## Step 2: Optimize SVG Files
We have a script to optimize SVG files for the icon system:
```bash
# Install dependencies
npm install
# Optimize a single SVG
npm run optimize-svg path/to/icon.svg
# Optimize all SVGs in a directory
npm run optimize-svg src/components/icons/ui/outline
```
The optimizer will:
- Remove unnecessary attributes
- Set the viewBox to "0 0 24 24"
- Add currentColor for fills/strokes for proper color inheritance
- Remove width and height attributes for flexible sizing
## Step 3: Add SVG Files to the Project
1. Decide if your icon is a "bold" (filled) or "outline" (stroked) variant
2. Place the file in the appropriate directory:
- For outline variants: `src/components/icons/ui/outline/`
- For bold variants: `src/components/icons/ui/bold/`
3. Use a descriptive name like `download.svg` or `settings.svg`
## Step 4: Export the Icons
1. Open the index.ts file in the respective directory:
- `src/components/icons/ui/outline/index.ts` for outline variants
- `src/components/icons/ui/bold/index.ts` for bold variants
2. Add an export statement for your new icon:
```typescript
// For outline variant
export { ReactComponent as NewIconOutlineIcon } from './new-icon.svg'
// For bold variant
export { ReactComponent as NewIconBoldIcon } from './new-icon.svg'
```
Use a consistent naming pattern:
- CamelCase
- Descriptive name
- Suffix with BoldIcon or OutlineIcon based on variant
## Step 5: Use the Icon in Your Components
Now you can use your new icon in any component:
```tsx
import { Icon } from '@/components/icons'
import { NewIconOutlineIcon, NewIconBoldIcon } from '@/components/icons'
// In your component:
<Icon icon={NewIconOutlineIcon} size="md" />
<Icon icon={NewIconBoldIcon} size="lg" fillColor="var(--primary-color)" />
```
## Best Practices
1. **Create both variants**: When possible, create both bold and outline variants for consistency.
2. **Use semantic names**: Name icons based on their meaning, not appearance (e.g., "success" instead of "checkmark").
3. **Be consistent**: Follow the existing icon style for visual harmony.
4. **Test different sizes**: Ensure icons look good at all standard sizes: xs, sm, md, lg, xl.
5. **Optimize manually if needed**: Sometimes automatic optimization may not work perfectly. You might need to manually edit SVG files.
6. **Add accessibility**: When using icons, provide proper accessibility:
```tsx
<Icon icon={InfoOutlineIcon} title="Additional information" size="md" />
```
## Troubleshooting
**Problem**: Icon doesn't change color with CSS
**Solution**: Make sure your SVG uses `currentColor` for fill or stroke
**Problem**: Icon looks pixelated
**Solution**: Ensure your SVG has a proper viewBox attribute
**Problem**: Icon sizing is inconsistent
**Solution**: Use the standard size props (xs, sm, md, lg, xl) instead of custom sizes
**Problem**: SVG has complex gradients or effects that don't render correctly
**Solution**: Simplify the SVG design; complex effects aren't ideal for UI icons
## Additional Resources
- [SVGR documentation](https://react-svgr.com/docs/what-is-svgr/)
- [SVGO documentation](https://github.com/svg/svgo)
- [SVG MDN documentation](https://developer.mozilla.org/en-US/docs/Web/SVG)

160
docs/icons.md Normal file
View File

@@ -0,0 +1,160 @@
# Icon Usage Methods
There are two ways to use icons in Creamlinux, both fully supported and completely interchangeable.
## Method 1: Using Icon component with name prop
This approach uses the `Icon` component with a `name` prop:
```tsx
import { Icon, refresh, check, info, steam } from '@/components/icons'
<Icon name={refresh} />
<Icon name={check} variant="bold" />
<Icon name={info} size="lg" fillColor="var(--info)" />
<Icon name={steam} /> {/* Brand icons auto-detect the variant */}
```
## Method 2: Using direct icon components
This approach imports pre-configured icon components directly:
```tsx
import { RefreshIcon, CheckBoldIcon, InfoIcon, SteamIcon } from '@/components/icons'
<RefreshIcon /> {/* Outline variant */}
<CheckBoldIcon /> {/* Bold variant */}
<InfoIcon size="lg" fillColor="var(--info)" />
<SteamIcon /> {/* Brand icon */}
```
## When to use each method
### Use Method 1 (Icon + name) when:
- You have dynamic icon selection based on data or state
- You want to keep your imports list shorter
- You're working with icons in loops or maps
- You want to change variants dynamically
Example of dynamic icon selection:
```tsx
import { Icon } from '@/components/icons'
function StatusIndicator({ status }) {
const iconName =
status === 'success'
? 'Check'
: status === 'warning'
? 'Warning'
: status === 'error'
? 'Close'
: 'Info'
return <Icon name={iconName} variant="bold" />
}
```
### Use Method 2 (direct components) when:
- You want the most concise syntax
- You're using a fixed set of icons that won't change
- You want specific variants (like InfoBoldIcon vs InfoIcon)
- You prefer more explicit component names in your JSX
Example of fixed icon usage:
```tsx
import { InfoIcon, CloseIcon } from '@/components/icons'
function ModalHeader({ title, onClose }) {
return (
<div className="modal-header">
<div className="title">
<InfoIcon size="sm" />
<h3>{title}</h3>
</div>
<button onClick={onClose}>
<CloseIcon size="md" />
</button>
</div>
)
}
```
## Available Icon Component Exports
### UI Icons (Outline variant by default)
```tsx
import {
ArrowUpIcon,
CheckIcon,
CloseIcon,
ControllerIcon,
CopyIcon,
DownloadIcon,
EditIcon,
InfoIcon,
LayersIcon,
RefreshIcon,
SearchIcon,
TrashIcon,
WarningIcon,
WineIcon,
} from '@/components/icons'
```
### Bold Variants
```tsx
import { CheckBoldIcon, InfoBoldIcon, WarningBoldIcon } from '@/components/icons'
```
### Brand Icons
```tsx
import { DiscordIcon, GitHubIcon, LinuxIcon, SteamIcon, WindowsIcon } from '@/components/icons'
```
## Combining Methods
Both methods work perfectly together and can be mixed in the same component:
```tsx
import {
Icon,
refresh, // Method 1
CheckBoldIcon, // Method 2
} from '@/components/icons'
function MyComponent() {
return (
<div>
<Icon name={refresh} />
<CheckBoldIcon />
</div>
)
}
```
## Props are Identical
Both methods accept the same props:
```tsx
// These are equivalent:
<InfoIcon size="lg" fillColor="blue" className="my-icon" />
<Icon name={info} size="lg" fillColor="blue" className="my-icon" />
```
Available props in both cases:
- `size`: "xs" | "sm" | "md" | "lg" | "xl" | number
- `variant`: "outline" | "bold" | "brand" (only for Icon + name method)
- `fillColor`: CSS color string
- `strokeColor`: CSS color string
- `className`: CSS class string
- `title`: Accessibility title
- ...plus all standard SVG attributes