mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 11:55:05 +03:00
This PR fixes some prettier issues: - Bump and unify all prettier versions to 3.7.3 across teh whole repo - Bump the SQL prettier plugin - When running `test:prettier`, check `mdx` files also - Run the new prettier format on all files --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
136 lines
5.4 KiB
Plaintext
136 lines
5.4 KiB
Plaintext
---
|
||
title: Icons
|
||
description: Icons make actions and navigation across Supabase easier.
|
||
---
|
||
|
||
## Principles
|
||
|
||
1. Paired: Icons should accompany text, as they aren’t often obvious enough on their own.
|
||
2. Clear: Icons should be legible at small sizes and unembellished. Let the text do the heavy lifting.
|
||
3. Consistent: Use the same icons for similar actions throughout Supabase. This makes the app easier to use.
|
||
|
||
## Tints
|
||
|
||
Use classes just like you would for [text](color-usage#text) to tint icons. For example:
|
||
|
||
```jsx
|
||
<BucketAdd className="text-foreground-muted" />
|
||
```
|
||
|
||
Just like text, don’t tint icons with `text-destructive` for destructive actions. There should be a confirmation dialog right after which can handle the destructive styling.
|
||
|
||
## UI icons
|
||
|
||
We rely on [Lucide](https://lucide.dev/icons/) for any standard UI icon needs.
|
||
|
||
## Custom icons
|
||
|
||
Create and use custom icons when Lucide doesn’t have the icon you need. Tap on an icon below to copy the JSX, SVG, or import path.
|
||
|
||
<Icons />
|
||
|
||
### Usage
|
||
|
||
```jsx
|
||
import { BucketAdd, InsertCode, ReplaceCode } from 'icons'
|
||
|
||
function app() {
|
||
return (
|
||
<>
|
||
<ReplaceCode className="text-light" strokeWidth={1} size={16} />
|
||
<InsertCode className="text-light" strokeWidth={1} size={16} />
|
||
<BucketAdd size={24} className="text-foreground-muted" />
|
||
</>
|
||
)
|
||
}
|
||
```
|
||
|
||
**Default props**: All icons default to `size={24}`. Stroke and fill defaults come from the source SVG's root attributes (e.g. `stroke-width="1"` on the root `<svg>` becomes the component's default `strokeWidth`). You can override those defaults at the call site, but any `stroke`, `fill`, or `stroke-width` set on individual child paths will still win.
|
||
|
||
### Adding new custom icons
|
||
|
||
Follow these steps to add a new custom icon to the Supabase icon library.
|
||
|
||
1. **Create SVG file**: Add your SVG file to `packages/icons/src/raw-icons/` with a kebab-case name (e.g., `my-new-icon.svg`). Make sure it follows these requirements:
|
||
- Exported at 24×24px with `viewBox="0 0 24 24"`
|
||
- Uses `stroke="currentColor"` for strokes (no hardcoded colors)
|
||
- Uses `stroke-width="1.5"` (deviate based on optical weight if necessary)
|
||
- Uses `fill="none"` for fills (no hardcoded colors)
|
||
- Icon content is optically centered and around 18×18px within the 24×24 frame
|
||
- Any unnecessary elements like `<clipPath>`, `<defs>`, and `<g>` wrappers have been removed
|
||
- SVG structure is as simple as possible with just `<path>` elements
|
||
|
||
For **fill-only icons** (e.g. logos that use shapes instead of strokes), add `stroke="none"` to the root `<svg>` element. The build will propagate this so the component never renders an unwanted stroke.
|
||
|
||
Prefer putting shared styling like `fill`, `stroke`, `stroke-width`, `stroke-linecap`, and `stroke-linejoin` on the root `<svg>`. The build propagates those root attributes as the component's defaults, and also converts them to camel-case for React compatibility (e.g. `strokeWidth`). If you put those attributes on individual child paths instead, they become fixed path-level styling and will override props passed to the component.
|
||
|
||
2. **Build the component**: Run `npm run build:icons` from inside the `packages/icons` directory
|
||
|
||
3. **Use the icon**: Import and use like any other icon:
|
||
|
||
```tsx
|
||
import { MyNewIcon } from 'icons'
|
||
```
|
||
|
||
```tsx
|
||
<MyNewIcon size={16} strokeWidth={1} />
|
||
```
|
||
|
||
The icon name is automatically made available in camel-case, determined by the kebab-case input SVG. For example, `my-new-icon.svg` will become available as `MyNewIcon`.
|
||
|
||
### SVG design guidelines
|
||
|
||
Icons should:
|
||
|
||
- Always be exported 24×24px
|
||
- Have an icon inside that frame that’s around 18×18px(ish)
|
||
- Use clean, simple paths without unnecessary wrapper elements
|
||
|
||
#### Bad example ❌
|
||
|
||
Notice the hardcoded colors, unnecessary backgrounds, and complex structure:
|
||
|
||
```svg
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<rect width="24" height="24" fill="#1E1E1E" /> <!-- ❌ Hardcoded color -->
|
||
<path d="M..." fill="#404040" /> <!-- ❌ Hardcoded color -->
|
||
<path d="M..." stroke="#EDEDED" stroke-linecap="round" /> <!-- ❌ Hardcoded color -->
|
||
</svg>
|
||
```
|
||
|
||
#### Good example (stroke icon) ✅
|
||
|
||
Clean structure with `currentColor` and proper attributes:
|
||
|
||
```svg
|
||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||
<path d="M6 7C6 4.2 8.2 2 11 2H13C15.8 2 18 4.2 18 7" />
|
||
<path d="M4.5 11H19.5" />
|
||
<path d="M6 11L6.8 20C6.9 21.1 7.9 22 9 22H12" />
|
||
</svg>
|
||
```
|
||
|
||
#### Good example (fill-only icon / logo) ✅
|
||
|
||
Note `stroke="none"` on the root to prevent unwanted strokes, and `fill="currentColor"` on each path:
|
||
|
||
```svg
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="none" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M..." fill="currentColor" />
|
||
</svg>
|
||
```
|
||
|
||
{/* This is still wrong: */}
|
||
|
||
```svg
|
||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M6 7C6 4.2 8.2 2 11 2H13C15.8 2 18 4.2 18 7" />
|
||
<path d="M4.5 11H19.5" />
|
||
<path d="M6 11L6.8 20C6.9 21.1 7.9 22 9 22H12" />
|
||
</svg>
|
||
```
|
||
|
||
### Troubleshooting
|
||
|
||
If your SVG specifies `stroke-width` attributes on individual child paths, they will override the component's `strokeWidth` prop. Keep shared stroke attributes on the root `<svg>` and remove them from individual paths if you want consumers to control stroke weight.
|