Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1980e3d59b | ||
|
|
aa0b77386c | ||
|
|
7bb15b80a3 |
@@ -56,7 +56,7 @@ When checking or adding a `$group:` marker:
|
||||
|
||||
- A marker must be exactly `"$group:"` followed by the name of an existing file in `groups/`, without the `.json` extension, in lowercase kebab-case.
|
||||
- `$group:` is allowed **only** inside `tags`. It is not valid in `categories` or `contributors`.
|
||||
- Groups are named after the variant suffix: `file-plus` uses `$group:plus`, `file-question-mark` uses `$group:question-mark`. Suffixes with the same meaning share a group: `mail-warning` uses `$group:exclamation-mark`, and every currency suffix uses `$group:currency`.
|
||||
- Groups are named after the variant suffix: `file-plus` uses `$group:plus`, `file-question-mark` uses `$group:question-mark`. Suffixes with the same meaning share a group: `mail-exclamation-point` uses `$group:exclamation-mark`, and every currency suffix uses `$group:currency`.
|
||||
- The same suffix can mean different things in different contexts — `-off` means "disabled" on `wifi-off` but "allergy free" on `wheat-off` — so only use the group when the icon carries the group's meaning, and keep context-specific tags as literals.
|
||||
- Do not repeat a tag a group already provides, and do not use the same group twice in one array.
|
||||
- Conventional order: the `$extends:` base icon first, then `$group:` markers, then the icon's own literal tags.
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
"$schema": "../category.schema.json",
|
||||
"title": "Notifications",
|
||||
"description": "Icons for alerts, status updates, reminders, approvals, and attention states.",
|
||||
"icon": "triangle-alert"
|
||||
"icon": "triangle-exclamation-point"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import Calendar from '../../../data/iconDetails/calendar.ts';
|
||||
import Clock from '../../../data/iconDetails/clock.ts';
|
||||
import Bug from '../../../data/iconDetails/bug.ts';
|
||||
import Rocket from '../../../data/iconDetails/rocket.ts';
|
||||
import TriangleAlert from '../../../data/iconDetails/triangle-alert.ts';
|
||||
import TriangleExclamationPoint from '../../../data/iconDetails/triangle-exclamation-point.ts';
|
||||
import PartyPopper from '../../../data/iconDetails/party-popper.ts';
|
||||
import Scissors from '../../../data/iconDetails/scissors.ts';
|
||||
import Copy from '../../../data/iconDetails/copy.ts';
|
||||
@@ -41,7 +41,7 @@ const CalendarIcon = createLucideIcon('calendar', Calendar.iconNode);
|
||||
const ClockIcon = createLucideIcon('clock', Clock.iconNode);
|
||||
const BugIcon = createLucideIcon('bug', Bug.iconNode);
|
||||
const RocketIcon = createLucideIcon('rocket', Rocket.iconNode);
|
||||
const AlertTriangleIcon = createLucideIcon('alert-triangle', TriangleAlert.iconNode);
|
||||
const TriangleExclamationPointIcon = createLucideIcon('triangle-exclamation-point', TriangleExclamationPoint.iconNode);
|
||||
const ScissorsIcon = createLucideIcon('scissors', Scissors.iconNode);
|
||||
const CopyIcon = createLucideIcon('copy', Copy.iconNode);
|
||||
const SaveIcon = createLucideIcon('save', Save.iconNode);
|
||||
@@ -128,7 +128,7 @@ const prettyName = props.name
|
||||
>
|
||||
<div class="placeholder"></div>
|
||||
<div class="badge badge-red">
|
||||
<AlertTriangleIcon :size="20" />
|
||||
<TriangleExclamationPointIcon :size="20" />
|
||||
Alert
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -117,8 +117,6 @@ function scrollTrack(direction: 1 | -1) {
|
||||
.tiers {
|
||||
padding-top: 96px;
|
||||
padding-bottom: 48px;
|
||||
/* The track bleeds to the right edge of the viewport. */
|
||||
overflow-x: clip;
|
||||
}
|
||||
|
||||
.tiers-header {
|
||||
@@ -165,7 +163,6 @@ function scrollTrack(direction: 1 | -1) {
|
||||
|
||||
.track-wrapper {
|
||||
position: relative;
|
||||
margin-right: min(-24px, calc((1152px - 100vw) / 2));
|
||||
}
|
||||
|
||||
.track {
|
||||
@@ -178,12 +175,16 @@ function scrollTrack(direction: 1 | -1) {
|
||||
padding-bottom: 12px;
|
||||
padding-right: 24px;
|
||||
scroll-padding-right: 24px;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-width: none;
|
||||
scroll-snap-align: center;
|
||||
scroll-padding-left: 24px;
|
||||
scroll-padding-right: 24px;
|
||||
}
|
||||
|
||||
.track::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.track:focus-visible {
|
||||
outline: 2px solid var(--vp-c-brand-1);
|
||||
outline-offset: 4px;
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Learn the best practices for writing use cases for Lucide icons.
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import { batteryLow, creditCard, crop, handshake, heading2, microchip, search, squareLetterP, triangleAlert, wifiOff } from '~/.vitepress/data/iconNodes';
|
||||
import { batteryLow, creditCard, crop, handshake, heading2, microchip, search, squareLetterP, triangleExclamationPoint, wifiOff } from '~/.vitepress/data/iconNodes';
|
||||
import LucideIcon from '~/.vitepress/theme/components/base/LucideIcon.vue';
|
||||
</script>
|
||||
|
||||
@@ -120,10 +120,10 @@ The period adds **unnecessary punctuation** and makes entries inconsistent.
|
||||
Use plain text only. Formatting belongs in documentation, not metadata values.
|
||||
|
||||
:::: example
|
||||
::: do <LucideIcon name="triangle-alert" :iconNode="triangleAlert" /> Warning users about a destructive action
|
||||
::: do <LucideIcon name="triangle-exclamation-point" :iconNode="triangleExclamationPoint" /> Warning users about a destructive action
|
||||
This works in search, generated pages, and other places that use metadata.
|
||||
:::
|
||||
::: dont <LucideIcon name="triangle-alert" :iconNode="triangleAlert" /> <span>**Warning** users about a destructive action ⚠️</span>
|
||||
::: dont <LucideIcon name="triangle-exclamation-point" :iconNode="triangleExclamationPoint" /> <span>**Warning** users about a destructive action ⚠️</span>
|
||||
Markdown and emoji can **show up in generated UI** and make metadata **harder to reuse**.
|
||||
:::
|
||||
::::
|
||||
|
||||
@@ -31,7 +31,7 @@ You can then reference the registered icons by name:
|
||||
|
||||
```html [app.html]
|
||||
<svg lucideIcon="square-check"></svg>
|
||||
<svg lucideIcon="circle-alert"></svg>
|
||||
<svg lucideIcon="circle-exclamation-point"></svg>
|
||||
```
|
||||
|
||||
## How names are resolved
|
||||
|
||||
@@ -15,5 +15,10 @@
|
||||
"categories": [
|
||||
"account",
|
||||
"social"
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"name": "badge-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 471 B After Width: | Height: | Size: 471 B |
@@ -12,5 +12,10 @@
|
||||
],
|
||||
"categories": [
|
||||
"$extends:battery"
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"name": "battery-warning"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 393 B After Width: | Height: | Size: 393 B |
@@ -15,5 +15,10 @@
|
||||
],
|
||||
"categories": [
|
||||
"$extends:book"
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"name": "book-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 359 B After Width: | Height: | Size: 359 B |
@@ -16,6 +16,9 @@
|
||||
"name": "alert-circle",
|
||||
"deprecationReason": "alias.name",
|
||||
"deprecated": true
|
||||
},
|
||||
{
|
||||
"name": "circle-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 332 B |
@@ -13,5 +13,10 @@
|
||||
],
|
||||
"categories": [
|
||||
"$extends:clock"
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"name": "clock-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 332 B |
@@ -19,5 +19,10 @@
|
||||
"development",
|
||||
"notifications",
|
||||
"weather"
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"name": "cloud-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 331 B After Width: | Height: | Size: 331 B |
@@ -13,5 +13,13 @@
|
||||
"categories": [
|
||||
"mail",
|
||||
"notifications"
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"name": "mail-warning"
|
||||
},
|
||||
{
|
||||
"name": "mail-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 393 B After Width: | Height: | Size: 393 B |
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"Prsenapati09",
|
||||
"rrod497"
|
||||
],
|
||||
"use-cases": [
|
||||
"Representing tropical fruit in food and grocery apps",
|
||||
"Indicating produce sections in shopping interfaces",
|
||||
"Labeling tropical fruit filters in recipe and nutrition apps",
|
||||
"Highlighting seasonal fruit in marketplaces"
|
||||
],
|
||||
"tags": [
|
||||
"fruit",
|
||||
"food",
|
||||
"tropical",
|
||||
"summer",
|
||||
"exotic",
|
||||
"healthy",
|
||||
"ripe",
|
||||
"yellow",
|
||||
"juice",
|
||||
"smoothie",
|
||||
"snack",
|
||||
"produce"
|
||||
],
|
||||
"categories": [
|
||||
"food-beverage"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="m17 6 3-3" />
|
||||
<path d="M7 22a4 4 0 01-2.62-7.023A2 2 0 005 13.383V10a8 8 0 1116 0A12 12 0 019 22z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 323 B |
@@ -17,5 +17,13 @@
|
||||
"categories": [
|
||||
"$extends:message-circle",
|
||||
"notifications"
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"name": "message-circle-warning"
|
||||
},
|
||||
{
|
||||
"name": "message-circle-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 396 B After Width: | Height: | Size: 396 B |
@@ -16,5 +16,13 @@
|
||||
"categories": [
|
||||
"$extends:message-square",
|
||||
"notifications"
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"name": "message-square-warning"
|
||||
},
|
||||
{
|
||||
"name": "message-square-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 388 B After Width: | Height: | Size: 388 B |
@@ -18,6 +18,9 @@
|
||||
"name": "alert-octagon",
|
||||
"deprecationReason": "alias.name",
|
||||
"deprecated": true
|
||||
},
|
||||
{
|
||||
"name": "octagon-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 510 B After Width: | Height: | Size: 510 B |
@@ -15,5 +15,10 @@
|
||||
],
|
||||
"categories": [
|
||||
"$extends:search"
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"name": "search-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 322 B After Width: | Height: | Size: 322 B |
@@ -59,5 +59,10 @@
|
||||
"development",
|
||||
"notifications",
|
||||
"gaming"
|
||||
],
|
||||
"aliases": [
|
||||
{
|
||||
"name": "shield-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 435 B |
@@ -21,6 +21,9 @@
|
||||
"name": "alert-triangle",
|
||||
"deprecationReason": "alias.name",
|
||||
"deprecated": true
|
||||
},
|
||||
{
|
||||
"name": "triangle-alert"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 345 B After Width: | Height: | Size: 345 B |
@@ -3,20 +3,20 @@ import { bootstrapApplication, provideClientHydration } from '@angular/platform-
|
||||
import { provideServerRendering, renderApplication } from '@angular/platform-server';
|
||||
import { LucideDynamicIcon } from './lucide-dynamic-icon';
|
||||
import { provideLucideIcons } from './lucide-icons';
|
||||
import { LucideBadgeAlert } from './icons/badge-alert';
|
||||
import { LucideBadgeExclamationPoint } from './icons/badge-exclamation-point';
|
||||
|
||||
@Component({
|
||||
// eslint-disable-next-line @angular-eslint/component-selector
|
||||
selector: 'lucide-static-hydration-root',
|
||||
template: `<svg lucideBadgeAlert [nonScalingStroke]="true"></svg>`,
|
||||
imports: [LucideBadgeAlert],
|
||||
template: `<svg lucideBadgeExclamationPoint [nonScalingStroke]="true"></svg>`,
|
||||
imports: [LucideBadgeExclamationPoint],
|
||||
})
|
||||
class StaticHydrationRootComponent {}
|
||||
|
||||
@Component({
|
||||
// eslint-disable-next-line @angular-eslint/component-selector
|
||||
selector: 'lucide-dynamic-hydration-root',
|
||||
template: `<svg [lucideIcon]="'badge-alert'"></svg>`,
|
||||
template: `<svg [lucideIcon]="'badge-exclamation-point'"></svg>`,
|
||||
imports: [LucideDynamicIcon],
|
||||
})
|
||||
class DynamicHydrationRootComponent {}
|
||||
@@ -60,7 +60,7 @@ describe('Lucide hydration', () => {
|
||||
);
|
||||
(globalThis as { ngServerMode?: boolean }).ngServerMode = false;
|
||||
const serverDocument = new DOMParser().parseFromString(html, 'text/html');
|
||||
expectBadgeAlertShapeNodes(serverDocument.querySelector('svg') as SVGSVGElement);
|
||||
expectBadgeExclamationPointShapeNodes(serverDocument.querySelector('svg') as SVGSVGElement);
|
||||
document.head.innerHTML = serverDocument.head.innerHTML;
|
||||
document.body.innerHTML = serverDocument.body.innerHTML;
|
||||
|
||||
@@ -75,7 +75,7 @@ describe('Lucide hydration', () => {
|
||||
return document.querySelector('svg') as SVGSVGElement;
|
||||
}
|
||||
|
||||
function expectBadgeAlertShapeNodes(svg: SVGSVGElement) {
|
||||
function expectBadgeExclamationPointShapeNodes(svg: SVGSVGElement) {
|
||||
expect(Array.from(svg.children).map((child) => child.tagName.toLowerCase())).toEqual([
|
||||
'path',
|
||||
'line',
|
||||
@@ -89,7 +89,7 @@ describe('Lucide hydration', () => {
|
||||
'lucide-static-hydration-root',
|
||||
);
|
||||
|
||||
expectBadgeAlertShapeNodes(svg);
|
||||
expectBadgeExclamationPointShapeNodes(svg);
|
||||
for (const child of Array.from(svg.children)) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
@@ -99,9 +99,9 @@ describe('Lucide hydration', () => {
|
||||
const svg = await renderAndHydrate(
|
||||
DynamicHydrationRootComponent,
|
||||
'lucide-dynamic-hydration-root',
|
||||
[provideLucideIcons(LucideBadgeAlert)],
|
||||
[provideLucideIcons(LucideBadgeExclamationPoint)],
|
||||
);
|
||||
|
||||
expectBadgeAlertShapeNodes(svg);
|
||||
expectBadgeExclamationPointShapeNodes(svg);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { promisify } from 'util';
|
||||
import simpleGit from 'simple-git';
|
||||
import { simpleGit } from 'simple-git';
|
||||
import { type IconMetadata } from '../../tools/build-icons/types.ts';
|
||||
|
||||
/**
|
||||
|
||||