mirror of
https://github.com/Novattz/creamlinux-installer.git
synced 2025-12-05 19:45:36 -05:00
Icons
This commit is contained in:
128
docs/adding-icons.md
Normal file
128
docs/adding-icons.md
Normal 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
160
docs/icons.md
Normal 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
|
||||
Reference in New Issue
Block a user