mirror of
https://github.com/lucide-icons/lucide.git
synced 2026-11-11 13:28:19 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03eae6069e |
@@ -15,6 +15,7 @@ monstera
|
||||
|
||||
# Search tags and terms used in icon and category metadata
|
||||
checkmark
|
||||
activitypub
|
||||
ageusia
|
||||
artboard
|
||||
barbeque
|
||||
@@ -22,6 +23,7 @@ choy
|
||||
cicd
|
||||
ecommerce
|
||||
enby
|
||||
fediverse
|
||||
flexbox
|
||||
futbol
|
||||
gddr
|
||||
|
||||
@@ -19,6 +19,10 @@ interface LucideProps extends SVGAttributes<SVGSVGElement> {
|
||||
size?: number | string;
|
||||
'stroke-width'?: number | string;
|
||||
nonScalingStroke?: boolean;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
[key: string]: any; // Any other SVG attributes
|
||||
}
|
||||
```
|
||||
|
||||
@@ -18,6 +18,10 @@ interface LucideProps {
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
nonScalingStroke?: boolean;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
[key: string]: any; // Any other SVG attributes
|
||||
}
|
||||
```
|
||||
|
||||
@@ -18,6 +18,10 @@ interface LucideProps {
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
nonScalingStroke?: boolean;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
[key: string]: any; // Any other SVG props, supported by react-native-svg
|
||||
}
|
||||
```
|
||||
|
||||
@@ -17,6 +17,10 @@ interface LucideProps {
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
nonScalingStroke?: boolean;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
[key: string]: any; // Any other SVG attributes
|
||||
}
|
||||
```
|
||||
|
||||
@@ -18,6 +18,10 @@ interface LucideProps extends SVGAttributes {
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
nonScalingStroke?: boolean;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
[key: string]: any; // Any other SVG attributes
|
||||
}
|
||||
```
|
||||
|
||||
@@ -19,6 +19,10 @@ interface LucideProps extends SVGAttributes<SVGSVGElement> {
|
||||
size?: number | string;
|
||||
strokeWidth?: number | string;
|
||||
nonScalingStroke?: boolean;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
children?: Snippet;
|
||||
[key: string]: any; // Any other SVG attributes
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@ interface LucideProps {
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
nonScalingStroke?: boolean;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
[key: string]: any; // Any other SVG attributes
|
||||
}
|
||||
```
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"KesleyDavid",
|
||||
"karsa-mistmere"
|
||||
],
|
||||
"use-cases": [
|
||||
"Marking interoperable Fediverse profile links in social clients",
|
||||
"Representing a three-star typographic symbol in publishing tools",
|
||||
"Separating article sections with a decorative typographic mark",
|
||||
"Representing star patterns in astronomy apps"
|
||||
],
|
||||
"tags": [
|
||||
"asterisk",
|
||||
"fediverse",
|
||||
"activitypub",
|
||||
"symbol",
|
||||
"typography",
|
||||
"social",
|
||||
"decentralized",
|
||||
"federation",
|
||||
"stars",
|
||||
"three",
|
||||
"ornament",
|
||||
"punctuation",
|
||||
"divider"
|
||||
],
|
||||
"categories": [
|
||||
"text"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<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="M12 2v8" />
|
||||
<path d="m14.5 15 7 4" />
|
||||
<path d="m14.5 19 7-4" />
|
||||
<path d="M18 13v8" />
|
||||
<path d="m2.5 15 7 4" />
|
||||
<path d="m2.5 19 7-4" />
|
||||
<path d="M6 13v8" />
|
||||
<path d="m8.5 4 7 4" />
|
||||
<path d="m8.5 8 7-4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 440 B |
@@ -13,7 +13,7 @@ export default function IconShowcase() {
|
||||
color="red"
|
||||
size={48}
|
||||
strokeWidth={4}
|
||||
nonScalingStroke
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
<LucideProvider
|
||||
color="purple"
|
||||
|
||||
@@ -17,15 +17,9 @@ test('renders Lucide public APIs in a real browser', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -12,7 +12,7 @@ export default function IconShowcase() {
|
||||
color="red"
|
||||
size={48}
|
||||
strokeWidth={4}
|
||||
nonScalingStroke
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
<LucideProvider
|
||||
color="purple"
|
||||
|
||||
@@ -37,12 +37,6 @@ test('renders Lucide public APIs and survives router navigation', async () => {
|
||||
expect(aliasIcon.element().innerHTML).toBe(canonicalIcon.element().innerHTML);
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function IconShowcase() {
|
||||
color="red"
|
||||
size={48}
|
||||
strokeWidth={4}
|
||||
nonScalingStroke
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
<LucideProvider
|
||||
color="purple"
|
||||
|
||||
@@ -22,15 +22,9 @@ test('renders Lucide public APIs and survives router navigation', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function IconShowcase() {
|
||||
color="red"
|
||||
size={48}
|
||||
strokeWidth={4}
|
||||
nonScalingStroke
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
<LucideProvider
|
||||
color="purple"
|
||||
|
||||
@@ -17,15 +17,9 @@ test('renders Lucide public APIs in a real browser', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -13,7 +13,7 @@ export default function IconShowcase() {
|
||||
color="red"
|
||||
size={48}
|
||||
strokeWidth={4}
|
||||
nonScalingStroke
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
<LucideProvider
|
||||
color="purple"
|
||||
|
||||
@@ -23,15 +23,9 @@ test('renders Lucide public APIs in a real browser', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function IconShowcase() {
|
||||
color="red"
|
||||
size={48}
|
||||
strokeWidth={4}
|
||||
nonScalingStroke
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
<LucideProvider
|
||||
color="purple"
|
||||
|
||||
@@ -22,15 +22,9 @@ test('renders Lucide public APIs and survives router navigation', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = page.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function IconShowcase() {
|
||||
color="red"
|
||||
size={48}
|
||||
strokeWidth={4}
|
||||
nonScalingStroke
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
<LucideProvider
|
||||
color="purple"
|
||||
|
||||
@@ -30,15 +30,9 @@ test('renders Lucide public APIs and survives router navigation', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function IconShowcase() {
|
||||
color="red"
|
||||
size={48}
|
||||
strokeWidth={4}
|
||||
nonScalingStroke
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
<LucideProvider
|
||||
color="purple"
|
||||
|
||||
@@ -17,15 +17,9 @@ test('renders Lucide public APIs in a real browser', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
color="red"
|
||||
size={48}
|
||||
strokeWidth={4}
|
||||
nonScalingStroke
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
<LucideProvider>
|
||||
<House data-testid="provider-icon" />
|
||||
|
||||
@@ -17,15 +17,9 @@ test('renders Lucide public APIs in a real browser', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
color="red"
|
||||
size={48}
|
||||
strokeWidth={4}
|
||||
nonScalingStroke
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
<LucideProvider>
|
||||
<House data-testid="provider-icon" />
|
||||
|
||||
@@ -17,15 +17,9 @@ test('renders Lucide public APIs in a real browser', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -12,7 +12,7 @@ import LucideProvider from './LucideProvider.vue';
|
||||
color="red"
|
||||
:size="48"
|
||||
:stroke-width="4"
|
||||
non-scaling-stroke
|
||||
absolute-stroke-width
|
||||
/>
|
||||
<LucideProvider>
|
||||
<House data-testid="provider-icon" />
|
||||
|
||||
@@ -17,15 +17,9 @@ test('renders Lucide public APIs in a real browser', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -12,7 +12,7 @@ import LucideProvider from './LucideProvider.vue';
|
||||
color="red"
|
||||
:size="48"
|
||||
:stroke-width="4"
|
||||
non-scaling-stroke
|
||||
absolute-stroke-width
|
||||
/>
|
||||
<LucideProvider>
|
||||
<House data-testid="provider-icon" />
|
||||
|
||||
@@ -17,15 +17,9 @@ test('renders Lucide public APIs in a real browser', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
@@ -12,7 +12,7 @@ import LucideProvider from './LucideProvider.vue';
|
||||
color="red"
|
||||
:size="48"
|
||||
:stroke-width="4"
|
||||
non-scaling-stroke
|
||||
absolute-stroke-width
|
||||
/>
|
||||
<LucideProvider>
|
||||
<House data-testid="provider-icon" />
|
||||
|
||||
@@ -17,15 +17,9 @@ test('renders Lucide public APIs in a real browser', async () => {
|
||||
await expect.element(customIcon).toHaveAttribute('width', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('height', '48');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke', 'red');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '4');
|
||||
await expect.element(customIcon).toHaveAttribute('stroke-width', '2');
|
||||
await expect.element(customIcon).toHaveClass('consumer-icon');
|
||||
|
||||
const customIconChildren = Array.from(customIcon.element().children);
|
||||
expect(customIconChildren.length).toBeGreaterThan(0);
|
||||
for (const child of customIconChildren) {
|
||||
expect(child.getAttribute('vector-effect')).toBe('non-scaling-stroke');
|
||||
}
|
||||
|
||||
const providerIcon = screen.getByTestId('provider-icon');
|
||||
await expect.element(providerIcon).toHaveAttribute('width', '32');
|
||||
await expect.element(providerIcon).toHaveAttribute('stroke', 'purple');
|
||||
|
||||
+1
File diff suppressed because one or more lines are too long
@@ -19,6 +19,11 @@ export interface LucideConfig {
|
||||
* @default 2
|
||||
*/
|
||||
strokeWidth: number;
|
||||
/**
|
||||
* Whether to use absolute stroke width.
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth: boolean;
|
||||
/**
|
||||
* Whether stroke width should be scaled to appear uniform regardless of icon size.
|
||||
* @default false
|
||||
@@ -41,6 +46,7 @@ export const lucideDefaultConfig: LucideConfig = {
|
||||
color: 'currentColor',
|
||||
size: 24,
|
||||
strokeWidth: 2,
|
||||
absoluteStrokeWidth: false,
|
||||
nonScalingStroke: false,
|
||||
};
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ describe('LucideIconBase', () => {
|
||||
let color: WritableSignal<string | undefined>;
|
||||
let size: WritableSignal<string | number | undefined>;
|
||||
let strokeWidth: WritableSignal<string | number | undefined>;
|
||||
let absoluteStrokeWidth: WritableSignal<boolean | undefined>;
|
||||
let nonScalingStroke: WritableSignal<boolean | undefined>;
|
||||
const getSvgAttribute = (attr: string) => fixture.nativeElement.getAttribute(attr);
|
||||
const expectSvgClasses = (classes: string[], svg: SVGElement = fixture.nativeElement) => {
|
||||
@@ -62,6 +63,7 @@ describe('LucideIconBase', () => {
|
||||
inputBinding('color', color),
|
||||
inputBinding('size', size),
|
||||
inputBinding('strokeWidth', strokeWidth),
|
||||
inputBinding('absoluteStrokeWidth', absoluteStrokeWidth),
|
||||
inputBinding('nonScalingStroke', nonScalingStroke),
|
||||
],
|
||||
});
|
||||
@@ -71,6 +73,7 @@ describe('LucideIconBase', () => {
|
||||
color = signal(undefined);
|
||||
size = signal(undefined);
|
||||
strokeWidth = signal(undefined);
|
||||
absoluteStrokeWidth = signal(undefined);
|
||||
nonScalingStroke = signal(undefined);
|
||||
fixture = createComponent();
|
||||
component = fixture.componentInstance;
|
||||
@@ -159,6 +162,22 @@ describe('LucideIconBase', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('absoluteStrokeWidth', () => {
|
||||
it('should adjust stroke width', () => {
|
||||
strokeWidth.set(2);
|
||||
size.set(32);
|
||||
absoluteStrokeWidth.set(true);
|
||||
fixture.detectChanges();
|
||||
expect(getSvgAttribute('stroke-width')).toBe('1.5');
|
||||
});
|
||||
it('should not set vector-effect on children', () => {
|
||||
absoluteStrokeWidth.set(true);
|
||||
for (const child of fixture.nativeElement.children) {
|
||||
expect(child.getAttribute('vector-effect')).toBeNull();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('nonScalingStroke', () => {
|
||||
it('should not adjust stroke width', () => {
|
||||
strokeWidth.set(2);
|
||||
@@ -213,6 +232,7 @@ describe('LucideIconBase', () => {
|
||||
strokeWidth: 1,
|
||||
size: 12,
|
||||
nonScalingStroke: true,
|
||||
absoluteStrokeWidth: true,
|
||||
}),
|
||||
],
|
||||
});
|
||||
@@ -234,12 +254,12 @@ describe('LucideIconBase', () => {
|
||||
describe('strokeWidth', () => {
|
||||
it('should use stroke width from config', () => {
|
||||
fixture.detectChanges();
|
||||
expect(getSvgAttribute('stroke-width')).toBe('1');
|
||||
expect(getSvgAttribute('stroke-width')).toBe('2');
|
||||
});
|
||||
it('should use override stroke width from config', () => {
|
||||
strokeWidth.set(3);
|
||||
fixture.detectChanges();
|
||||
expect(getSvgAttribute('stroke-width')).toBe('3');
|
||||
expect(getSvgAttribute('stroke-width')).toBe('6');
|
||||
});
|
||||
});
|
||||
describe('size', () => {
|
||||
@@ -255,6 +275,17 @@ describe('LucideIconBase', () => {
|
||||
expect(getSvgAttribute('height')).toBe('48');
|
||||
});
|
||||
});
|
||||
describe('absoluteStrokeWidth', () => {
|
||||
it('should use absoluteStrokeWidth from config', () => {
|
||||
fixture.detectChanges();
|
||||
expect(getSvgAttribute('stroke-width')).toBe('2');
|
||||
});
|
||||
it('should override absoluteStrokeWidth', () => {
|
||||
absoluteStrokeWidth.set(false);
|
||||
fixture.detectChanges();
|
||||
expect(getSvgAttribute('stroke-width')).toBe('1');
|
||||
});
|
||||
});
|
||||
describe('nonScalingStroke', () => {
|
||||
it('should use nonScalingStroke from config', () => {
|
||||
for (const child of fixture.nativeElement.children) {
|
||||
|
||||
@@ -73,6 +73,12 @@ export abstract class LucideIconBase {
|
||||
readonly strokeWidth = input(this.iconConfig.strokeWidth, {
|
||||
transform: (value: Nullable<string | number>) => value ?? this.iconConfig.strokeWidth,
|
||||
});
|
||||
/**
|
||||
* Whether to use absolute stroke width.
|
||||
*/
|
||||
readonly absoluteStrokeWidth = input(this.iconConfig.absoluteStrokeWidth, {
|
||||
transform: (value: Nullable<boolean>) => value ?? this.iconConfig.absoluteStrokeWidth,
|
||||
});
|
||||
/**
|
||||
* If set to true, it adds [`vector-effect="non-scaling-stroke"`](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/vector-effect) to child elements.
|
||||
*/
|
||||
@@ -91,6 +97,7 @@ export abstract class LucideIconBase {
|
||||
height: this.height() ?? this.size(),
|
||||
color: this.color(),
|
||||
strokeWidth: this.strokeWidth(),
|
||||
absoluteStrokeWidth: this.absoluteStrokeWidth(),
|
||||
nonScalingStroke: this.nonScalingStroke(),
|
||||
className: this.class() ?? undefined,
|
||||
hasA11yProp: this.title() != null,
|
||||
|
||||
@@ -20,6 +20,10 @@ interface LucideIconProps {
|
||||
size: Signal<Nullable<number | string>>;
|
||||
color: Signal<Nullable<string>>;
|
||||
strokeWidth: Signal<Nullable<number | string>>;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth: Signal<Nullable<boolean>>;
|
||||
nonScalingStroke: Signal<Nullable<boolean>>;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ const {
|
||||
width,
|
||||
height,
|
||||
'stroke-width': strokeWidth = 2,
|
||||
absoluteStrokeWidth = false,
|
||||
nonScalingStroke = false,
|
||||
iconNode = [],
|
||||
icon = {
|
||||
@@ -25,6 +26,7 @@ const [, builtIconAttributes, builtIconNode = []] = buildLucideIconNode(icon, {
|
||||
width: width ?? size,
|
||||
height: height ?? size,
|
||||
strokeWidth,
|
||||
absoluteStrokeWidth,
|
||||
nonScalingStroke,
|
||||
...(className !== undefined && { className }),
|
||||
hasA11yProp: hasA11yProp(rest),
|
||||
|
||||
@@ -11,6 +11,10 @@ export type LucideProps = SVGAttributes & {
|
||||
color?: string;
|
||||
size?: number | string;
|
||||
'stroke-width'?: number | string;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
class?: string;
|
||||
title?: string;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Icon, Rocket } from '../src/lucide-astro';
|
||||
|
||||
describe('Using Icon Component', async () => {
|
||||
const { container } = await render(Icon, {
|
||||
props: { iconNode: airVent, size: 48, stroke: 'red' },
|
||||
props: { iconNode: airVent, size: 48, stroke: 'red', absoluteStrokeWidth: true },
|
||||
});
|
||||
|
||||
it('should render icon and match snapshot', async () => {
|
||||
@@ -24,6 +24,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode: airVent,
|
||||
size: 48,
|
||||
stroke: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -35,6 +36,7 @@ describe('Icon Component Accessibility', () => {
|
||||
props: {
|
||||
size: 48,
|
||||
stroke: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
'aria-label': 'Release icon',
|
||||
},
|
||||
});
|
||||
@@ -47,6 +49,7 @@ describe('Icon Component Accessibility', () => {
|
||||
props: {
|
||||
size: 48,
|
||||
stroke: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
title: 'Release icon',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
viewbox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="red"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide"
|
||||
|
||||
@@ -208,3 +208,34 @@ exports[`Using lucide icon components > should render the icon with default attr
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using lucide icon components > should scale the strokeWidth when absoluteStrokeWidth is set 1`] = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="48"
|
||||
height="48"
|
||||
viewbox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="red"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-grid-3x3 lucide-grid lucide-grid-3-x-3"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
x="3"
|
||||
y="3"
|
||||
rx="2"
|
||||
>
|
||||
</rect>
|
||||
<path d="M3 9h18">
|
||||
</path>
|
||||
<path d="M3 15h18">
|
||||
</path>
|
||||
<path d="M9 3v18">
|
||||
</path>
|
||||
<path d="M15 3v18">
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
@@ -65,6 +65,25 @@ describe('Using lucide icon components', () => {
|
||||
expect(PenIconContainer.innerHTML).toBe(Edit2Container.innerHTML);
|
||||
});
|
||||
|
||||
it('should scale the strokeWidth when absoluteStrokeWidth is set', async () => {
|
||||
const { container } = await render(Grid, {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
},
|
||||
});
|
||||
|
||||
const SVGElement = container.firstElementChild;
|
||||
|
||||
expect(SVGElement).toHaveAttribute('stroke', 'red');
|
||||
expect(SVGElement).toHaveAttribute('width', '48');
|
||||
expect(SVGElement).toHaveAttribute('height', '48');
|
||||
expect(SVGElement).toHaveAttribute('stroke-width', '1');
|
||||
|
||||
expect(container.innerHTML).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should apply vector-effect when nonScalingStroke is set', async () => {
|
||||
const { container } = await render(Grid, {
|
||||
props: {
|
||||
|
||||
@@ -52,6 +52,26 @@ describe('buildLucideIconNode', () => {
|
||||
expect(HouseSVG[1]['stroke-width']).toBe(12);
|
||||
});
|
||||
|
||||
it('should scale the stroke width', () => {
|
||||
const HouseSVG = buildLucideIconNode(House, {
|
||||
size: 12,
|
||||
strokeWidth: 2,
|
||||
absoluteStrokeWidth: true,
|
||||
});
|
||||
|
||||
expect(HouseSVG[1]['stroke-width']).toBe(4);
|
||||
});
|
||||
|
||||
it('should not scale the stroke width', () => {
|
||||
const HouseSVG = buildLucideIconNode(House, {
|
||||
size: 12,
|
||||
strokeWidth: 2,
|
||||
absoluteStrokeWidth: false,
|
||||
});
|
||||
|
||||
expect(HouseSVG[1]['stroke-width']).toBe(2);
|
||||
});
|
||||
|
||||
it('should set non-scaling-stroke to child nodes', () => {
|
||||
const HouseSVG = buildLucideIconNode(House, { nonScalingStroke: true });
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ type IconComponentProps = LucideProps &
|
||||
* @param {string} props.color - The color of the icon
|
||||
* @param {number} props.size - The size of the icon
|
||||
* @param {number} props.strokeWidth - The stroke width of the icon
|
||||
* @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width
|
||||
* @param {boolean} props.nonScalingStroke - Whether to use non scaling strokes
|
||||
* @param {string} props.class - The class name of the icon
|
||||
* @param {LucideIconNode[]} props.children - The children of the icon
|
||||
@@ -36,6 +37,7 @@ const Icon = ({
|
||||
width,
|
||||
height,
|
||||
strokeWidth,
|
||||
absoluteStrokeWidth,
|
||||
nonScalingStroke,
|
||||
children,
|
||||
iconNode = [],
|
||||
@@ -50,6 +52,7 @@ const Icon = ({
|
||||
const {
|
||||
size: contextSize = 24,
|
||||
strokeWidth: contextStrokeWidth = 2,
|
||||
absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,
|
||||
nonScalingStroke: contextNonScalingStroke = false,
|
||||
color: contextColor = 'currentColor',
|
||||
class: contextClass = '',
|
||||
@@ -60,6 +63,7 @@ const Icon = ({
|
||||
width: width ?? size ?? contextSize,
|
||||
height: height ?? size ?? contextSize,
|
||||
strokeWidth: strokeWidth ?? contextStrokeWidth,
|
||||
absoluteStrokeWidth: absoluteStrokeWidth ?? contextAbsoluteStrokeWidth,
|
||||
nonScalingStroke: nonScalingStroke ?? contextNonScalingStroke,
|
||||
className: mergeClasses(contextClass, classes as string),
|
||||
hasA11yProp: Boolean(children) || hasA11yProp(rest),
|
||||
|
||||
@@ -5,12 +5,17 @@ const LucideContext = createContext<{
|
||||
size?: number;
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
class?: string;
|
||||
}>({
|
||||
size: 24,
|
||||
color: 'currentColor',
|
||||
strokeWidth: 2,
|
||||
absoluteStrokeWidth: false,
|
||||
nonScalingStroke: false,
|
||||
class: '',
|
||||
});
|
||||
@@ -20,6 +25,10 @@ interface LucideProviderProps {
|
||||
size?: number;
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
class?: string;
|
||||
}
|
||||
@@ -29,6 +38,7 @@ export function LucideProvider({
|
||||
size,
|
||||
color,
|
||||
strokeWidth,
|
||||
absoluteStrokeWidth,
|
||||
nonScalingStroke,
|
||||
class: className,
|
||||
}: LucideProviderProps) {
|
||||
@@ -37,10 +47,11 @@ export function LucideProvider({
|
||||
size,
|
||||
color,
|
||||
strokeWidth,
|
||||
absoluteStrokeWidth,
|
||||
nonScalingStroke,
|
||||
class: className,
|
||||
}),
|
||||
[size, color, strokeWidth, nonScalingStroke, className],
|
||||
[size, color, strokeWidth, absoluteStrokeWidth, nonScalingStroke, className],
|
||||
);
|
||||
|
||||
return h(LucideContext.Provider, { value }, children);
|
||||
|
||||
@@ -19,6 +19,10 @@ export interface LucideProps extends Partial<Omit<SVGAttributes, 'ref' | 'size'>
|
||||
width?: string | number;
|
||||
height?: string | number;
|
||||
strokeWidth?: string | number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -23,6 +24,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -37,6 +39,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
aria-label="Air conditioning"
|
||||
/>,
|
||||
);
|
||||
@@ -50,6 +53,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
title="Air conditioning"
|
||||
/>,
|
||||
);
|
||||
@@ -63,6 +67,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
>
|
||||
<title>Some title</title>
|
||||
</Icon>,
|
||||
@@ -77,6 +82,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
aria-hidden={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
viewBox="0 0 24 24"
|
||||
width="48"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@@ -101,3 +101,34 @@ exports[`Using lucide icon components > should render an component 1`] = `
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using lucide icon components > should scale the strokeWidth when absoluteStrokeWidth is set 1`] = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="48"
|
||||
height="48"
|
||||
viewbox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="red"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-grid-3x3 lucide-grid lucide-grid-3-x-3"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
x="3"
|
||||
y="3"
|
||||
rx="2"
|
||||
>
|
||||
</rect>
|
||||
<path d="M3 9h18">
|
||||
</path>
|
||||
<path d="M3 15h18">
|
||||
</path>
|
||||
<path d="M9 3v18">
|
||||
</path>
|
||||
<path d="M15 3v18">
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
@@ -35,6 +35,22 @@ describe('Using LucideProvider', () => {
|
||||
expect(IconComponent).toHaveAttribute('stroke-width', '4');
|
||||
});
|
||||
|
||||
it('should render the icon with LucideProvider and custom absoluteStrokeWidth', () => {
|
||||
const { container } = render(
|
||||
<LucideProvider
|
||||
size={48}
|
||||
color="red"
|
||||
absoluteStrokeWidth
|
||||
>
|
||||
<House />
|
||||
</LucideProvider>,
|
||||
);
|
||||
|
||||
const IconComponent = container.firstElementChild;
|
||||
|
||||
expect(IconComponent).toHaveAttribute('stroke-width', '1');
|
||||
});
|
||||
|
||||
it('should render the icon with LucideProvider and custom nonScalingStroke', () => {
|
||||
const { container } = render(
|
||||
<LucideProvider
|
||||
|
||||
@@ -70,6 +70,25 @@ describe('Using lucide icon components', () => {
|
||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
|
||||
});
|
||||
|
||||
it('should scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||
const { container } = render(
|
||||
<Grid
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
const SVGElement = container.firstElementChild;
|
||||
|
||||
expect(SVGElement).toHaveAttribute('stroke', 'red');
|
||||
expect(SVGElement).toHaveAttribute('width', '48');
|
||||
expect(SVGElement).toHaveAttribute('height', '48');
|
||||
expect(SVGElement).toHaveAttribute('stroke-width', '1');
|
||||
|
||||
expect(container.innerHTML).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should apply vector-effect when nonScalingStroke is set', () => {
|
||||
const { container } = render(
|
||||
<Grid
|
||||
|
||||
@@ -44,6 +44,7 @@ const toNativeSvgAttributes = (attributes: Record<string, unknown>) => {
|
||||
* @param {string} props.color - The color of the icon
|
||||
* @param {number} props.size - The size of the icon
|
||||
* @param {number} props.strokeWidth - The stroke width of the icon
|
||||
* @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width
|
||||
* @param {string} props.className - The class name of the icon
|
||||
* @param {LucideIconNode[]} props.children - The children of the icon
|
||||
* @param {LucideIconNode[]} props.iconNode - The icon node of the icon
|
||||
@@ -58,6 +59,7 @@ const Icon = forwardRef<SVGSVGElement, IconComponentProps>(
|
||||
width = size,
|
||||
height = size,
|
||||
strokeWidth,
|
||||
absoluteStrokeWidth,
|
||||
nonScalingStroke,
|
||||
children,
|
||||
iconNode = [],
|
||||
@@ -74,6 +76,7 @@ const Icon = forwardRef<SVGSVGElement, IconComponentProps>(
|
||||
const {
|
||||
size: contextSize = 24,
|
||||
strokeWidth: contextStrokeWidth = 2,
|
||||
absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,
|
||||
nonScalingStroke: contextNonScalingStroke = false,
|
||||
color: contextColor = 'currentColor',
|
||||
className: contextClass = '',
|
||||
@@ -86,6 +89,7 @@ const Icon = forwardRef<SVGSVGElement, IconComponentProps>(
|
||||
width: width ?? size ?? contextSize,
|
||||
height: height ?? size ?? contextSize,
|
||||
strokeWidth: strokeWidth ?? contextStrokeWidth,
|
||||
absoluteStrokeWidth: absoluteStrokeWidth ?? contextAbsoluteStrokeWidth,
|
||||
nonScalingStroke: nonScalingStroke ?? contextNonScalingStroke,
|
||||
className: mergeClasses(contextClass, className),
|
||||
hasA11yProp: hasAccessibleProp,
|
||||
|
||||
@@ -4,12 +4,17 @@ const LucideContext = createContext<{
|
||||
size?: number;
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
className?: string;
|
||||
}>({
|
||||
size: 24,
|
||||
color: 'currentColor',
|
||||
strokeWidth: 2,
|
||||
absoluteStrokeWidth: false,
|
||||
nonScalingStroke: false,
|
||||
className: '',
|
||||
});
|
||||
@@ -19,6 +24,10 @@ interface LucideProviderProps {
|
||||
size?: number;
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
@@ -28,6 +37,7 @@ export function LucideProvider({
|
||||
size,
|
||||
color,
|
||||
strokeWidth,
|
||||
absoluteStrokeWidth,
|
||||
nonScalingStroke,
|
||||
className,
|
||||
}: LucideProviderProps) {
|
||||
@@ -36,10 +46,11 @@ export function LucideProvider({
|
||||
size,
|
||||
color,
|
||||
strokeWidth,
|
||||
absoluteStrokeWidth,
|
||||
nonScalingStroke,
|
||||
className,
|
||||
}),
|
||||
[size, color, strokeWidth, nonScalingStroke, className],
|
||||
[size, color, strokeWidth, absoluteStrokeWidth, nonScalingStroke, className],
|
||||
);
|
||||
|
||||
return createElement(LucideContext.Provider, { value }, children);
|
||||
|
||||
@@ -19,6 +19,10 @@ export interface LucideProps extends SvgProps {
|
||||
width?: string | number;
|
||||
height?: string | number;
|
||||
className?: string;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
'data-testid'?: string;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -29,6 +30,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
viewBox="0 0 24 24"
|
||||
width="48"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -20,7 +20,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
/>
|
||||
<path
|
||||
d="M6 8h12"
|
||||
@@ -28,7 +28,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
/>
|
||||
<path
|
||||
d="M18.3 17.7a2.5 2.5 0 0 1-3.16 3.83 2.53 2.53 0 0 1-1.14-2V12"
|
||||
@@ -36,7 +36,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
/>
|
||||
<path
|
||||
d="M6.6 15.6A2 2 0 1 0 10 17v-5"
|
||||
@@ -44,7 +44,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
@@ -248,6 +248,66 @@ exports[`Using lucide icon components > should render an component 1`] = `
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using lucide icon components > should scale the strokeWidth when absoluteStrokeWidth is set 1`] = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="48"
|
||||
height="48"
|
||||
viewbox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="red"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-grid-3x3 lucide-grid lucide-grid-3-x-3"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<rect fill="none"
|
||||
stroke="red"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
width="18"
|
||||
height="18"
|
||||
x="3"
|
||||
y="3"
|
||||
rx="2"
|
||||
>
|
||||
</rect>
|
||||
<path fill="none"
|
||||
stroke="red"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M3 9h18"
|
||||
>
|
||||
</path>
|
||||
<path fill="none"
|
||||
stroke="red"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M3 15h18"
|
||||
>
|
||||
</path>
|
||||
<path fill="none"
|
||||
stroke="red"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M9 3v18"
|
||||
>
|
||||
</path>
|
||||
<path fill="none"
|
||||
stroke="red"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M15 3v18"
|
||||
>
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using lucide icon components > should work with a single child component 1`] = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
|
||||
@@ -37,6 +37,23 @@ describe('Using LucideProvider', () => {
|
||||
expect(IconComponent).toHaveAttribute('stroke-width', '4');
|
||||
});
|
||||
|
||||
it('should render the icon with LucideProvider and custom absoluteStrokeWidth', () => {
|
||||
cleanup();
|
||||
const { container } = render(
|
||||
<LucideProvider
|
||||
size={48}
|
||||
color="red"
|
||||
absoluteStrokeWidth
|
||||
>
|
||||
<House />
|
||||
</LucideProvider>,
|
||||
);
|
||||
|
||||
const IconComponent = container.firstElementChild;
|
||||
|
||||
expect(IconComponent).toHaveAttribute('stroke-width', '1');
|
||||
});
|
||||
|
||||
it("should override the provider's global props when passing props to the icon", () => {
|
||||
cleanup();
|
||||
const { container } = render(
|
||||
|
||||
@@ -63,6 +63,25 @@ describe('Using lucide icon components', () => {
|
||||
expect(penIcon).toStrictEqual(edit2Icon);
|
||||
});
|
||||
|
||||
it('should scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||
const { container } = render(
|
||||
<Grid
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
const SVGElement = container.firstElementChild;
|
||||
|
||||
expect(SVGElement).toHaveAttribute('stroke', 'red');
|
||||
expect(SVGElement).toHaveAttribute('width', '48');
|
||||
expect(SVGElement).toHaveAttribute('height', '48');
|
||||
expect(SVGElement).toHaveAttribute('stroke-width', '1');
|
||||
|
||||
expect(container.innerHTML).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should apply vector-effect when nonScalingStroke is set', () => {
|
||||
const { container } = render(
|
||||
<Grid
|
||||
|
||||
@@ -42,6 +42,7 @@ async function getIconData(name: IconName) {
|
||||
* @param {string} props.color - The color of the icon
|
||||
* @param {number} props.size - The size of the icon
|
||||
* @param {number} props.strokeWidth - The stroke width of the icon
|
||||
* @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width
|
||||
* @param {boolean} props.nonScalingStroke - Whether to use non scaling strokes
|
||||
* @param {string} props.className - The class name of the icon
|
||||
* @param {LucideIconNode[]} props.children - The children of the icon
|
||||
|
||||
@@ -25,6 +25,7 @@ type IconComponentProps = LucideProps &
|
||||
* @param {string} props.color - The color of the icon
|
||||
* @param {number} props.size - The size of the icon
|
||||
* @param {number} props.strokeWidth - The stroke width of the icon
|
||||
* @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width
|
||||
* @param {boolean} props.nonScalingStroke - Whether to use non scaling strokes
|
||||
* @param {string} props.className - The class name of the icon
|
||||
* @param {LucideIconNode[]} props.children - The children of the icon
|
||||
@@ -40,6 +41,7 @@ const Icon = forwardRef<SVGSVGElement, IconComponentProps>(
|
||||
width,
|
||||
height,
|
||||
strokeWidth,
|
||||
absoluteStrokeWidth,
|
||||
nonScalingStroke,
|
||||
className = '',
|
||||
children,
|
||||
@@ -56,6 +58,7 @@ const Icon = forwardRef<SVGSVGElement, IconComponentProps>(
|
||||
const {
|
||||
size: contextSize = 24,
|
||||
strokeWidth: contextStrokeWidth = 2,
|
||||
absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,
|
||||
nonScalingStroke: contextNonScalingStroke = false,
|
||||
color: contextColor = 'currentColor',
|
||||
className: contextClass = '',
|
||||
@@ -68,6 +71,7 @@ const Icon = forwardRef<SVGSVGElement, IconComponentProps>(
|
||||
width: width ?? size ?? contextSize,
|
||||
height: height ?? size ?? contextSize,
|
||||
strokeWidth: strokeWidth ?? contextStrokeWidth,
|
||||
absoluteStrokeWidth: absoluteStrokeWidth ?? contextAbsoluteStrokeWidth,
|
||||
nonScalingStroke: nonScalingStroke ?? contextNonScalingStroke,
|
||||
className: mergeClasses(contextClass, className),
|
||||
hasA11yProp: hasAccessibleProp,
|
||||
|
||||
@@ -7,6 +7,10 @@ type LucideConfig = {
|
||||
size: number;
|
||||
color: string;
|
||||
strokeWidth: number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth: boolean;
|
||||
nonScalingStroke: boolean;
|
||||
className: string;
|
||||
};
|
||||
@@ -22,6 +26,7 @@ export function LucideProvider({
|
||||
size,
|
||||
color,
|
||||
strokeWidth,
|
||||
absoluteStrokeWidth,
|
||||
nonScalingStroke,
|
||||
className,
|
||||
}: LucideProviderProps) {
|
||||
@@ -30,10 +35,11 @@ export function LucideProvider({
|
||||
size,
|
||||
color,
|
||||
strokeWidth,
|
||||
absoluteStrokeWidth,
|
||||
nonScalingStroke,
|
||||
className,
|
||||
}),
|
||||
[size, color, strokeWidth, nonScalingStroke, className],
|
||||
[size, color, strokeWidth, absoluteStrokeWidth, nonScalingStroke, className],
|
||||
);
|
||||
|
||||
return createElement(LucideContext.Provider, { value }, children);
|
||||
|
||||
@@ -19,6 +19,10 @@ type ElementAttributes = RefAttributes<SVGSVGElement> & SVGAttributes;
|
||||
|
||||
export interface LucideProps extends ElementAttributes {
|
||||
size?: string | number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ describe('Using DynamicIcon Component', () => {
|
||||
name="circle"
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -23,6 +24,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -37,6 +39,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -49,6 +52,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
aria-label="Air conditioning"
|
||||
/>,
|
||||
);
|
||||
@@ -62,6 +66,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
// @ts-expect-error
|
||||
title="Air conditioning"
|
||||
/>,
|
||||
@@ -76,6 +81,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
>
|
||||
<title>Some title</title>
|
||||
</Icon>,
|
||||
@@ -90,6 +96,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
aria-hidden={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
viewBox="0 0 24 24"
|
||||
width="48"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@@ -23,6 +23,29 @@ exports[`Using LucideProvider > should render the icon with LucideProvider 1`] =
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using LucideProvider > should render the icon with LucideProvider and custom absoluteStrokeWidth 1`] = `
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="lucide lucide-house lucide-home"
|
||||
fill="none"
|
||||
height="48"
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="1"
|
||||
viewBox="0 0 24 24"
|
||||
width="48"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"
|
||||
/>
|
||||
<path
|
||||
d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using LucideProvider > should render the icon with LucideProvider and custom nonScalingStroke 1`] = `
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
|
||||
@@ -7,7 +7,7 @@ exports[`Using dynamicImports > should render icons dynamically by using the dyn
|
||||
viewbox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="red"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-face-slightly-smiling lucide-smile"
|
||||
|
||||
@@ -101,3 +101,34 @@ exports[`Using lucide icon components > should render an component 1`] = `
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using lucide icon components > should scale the strokeWidth when absoluteStrokeWidth is set 1`] = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="48"
|
||||
height="48"
|
||||
viewbox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="red"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-grid-3x3 lucide-grid lucide-grid-3-x-3"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
x="3"
|
||||
y="3"
|
||||
rx="2"
|
||||
>
|
||||
</rect>
|
||||
<path d="M3 9h18">
|
||||
</path>
|
||||
<path d="M3 15h18">
|
||||
</path>
|
||||
<path d="M9 3v18">
|
||||
</path>
|
||||
<path d="M15 3v18">
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
@@ -46,6 +46,23 @@ describe('Using LucideProvider', () => {
|
||||
expect(IconComponent).toHaveAttribute('stroke-width', '4');
|
||||
});
|
||||
|
||||
it('should render the icon with LucideProvider and custom absoluteStrokeWidth', () => {
|
||||
const { container } = render(
|
||||
<LucideProvider
|
||||
size={48}
|
||||
color="red"
|
||||
absoluteStrokeWidth
|
||||
>
|
||||
<House />
|
||||
</LucideProvider>,
|
||||
);
|
||||
|
||||
const IconComponent = container.firstElementChild;
|
||||
|
||||
expect(IconComponent).toHaveAttribute('stroke-width', '1');
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the icon with LucideProvider and custom nonScalingStroke', () => {
|
||||
const { container } = render(
|
||||
<LucideProvider
|
||||
|
||||
@@ -27,6 +27,7 @@ describe('Using dynamicImports', () => {
|
||||
name="smile"
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
|
||||
@@ -69,6 +69,25 @@ describe('Using lucide icon components', () => {
|
||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
|
||||
});
|
||||
|
||||
it('should scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||
const { container, getByTestId } = render(
|
||||
<Grid
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>,
|
||||
);
|
||||
|
||||
const SVGElement = container.firstElementChild;
|
||||
|
||||
expect(SVGElement).toHaveAttribute('stroke', 'red');
|
||||
expect(SVGElement).toHaveAttribute('width', '48');
|
||||
expect(SVGElement).toHaveAttribute('height', '48');
|
||||
expect(SVGElement).toHaveAttribute('stroke-width', '1');
|
||||
|
||||
expect(container.innerHTML).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should apply vector-effect when nonScalingStroke is set', () => {
|
||||
const { container, getByTestId } = render(
|
||||
<Grid
|
||||
|
||||
@@ -25,6 +25,7 @@ const Icon = (props: LucideProps & IconProps) => {
|
||||
'class',
|
||||
'icon',
|
||||
'iconNode',
|
||||
'absoluteStrokeWidth',
|
||||
'nonScalingStroke',
|
||||
]);
|
||||
|
||||
@@ -45,6 +46,7 @@ const Icon = (props: LucideProps & IconProps) => {
|
||||
width: localProps.width ?? localProps.size ?? globalProps.size,
|
||||
height: localProps.height ?? localProps.size ?? globalProps.size,
|
||||
strokeWidth: localProps.strokeWidth ?? globalProps.strokeWidth,
|
||||
absoluteStrokeWidth: localProps.absoluteStrokeWidth ?? globalProps.absoluteStrokeWidth,
|
||||
nonScalingStroke: localProps.nonScalingStroke ?? globalProps.nonScalingStroke,
|
||||
className: mergeClasses('lucide-icon', globalProps.class, localProps.class),
|
||||
hasA11yProp: Boolean(localProps.children) || hasA11yProp(rest),
|
||||
|
||||
@@ -4,12 +4,17 @@ export const LucideContext = createContext<{
|
||||
size?: number;
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
class?: string;
|
||||
}>({
|
||||
size: 24,
|
||||
color: 'currentColor',
|
||||
strokeWidth: 2,
|
||||
absoluteStrokeWidth: false,
|
||||
nonScalingStroke: false,
|
||||
class: '',
|
||||
});
|
||||
@@ -19,6 +24,10 @@ interface LucideProviderProps {
|
||||
size?: number;
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
class?: string;
|
||||
}
|
||||
@@ -28,6 +37,7 @@ export function LucideProvider(props: LucideProviderProps) {
|
||||
'size',
|
||||
'color',
|
||||
'strokeWidth',
|
||||
'absoluteStrokeWidth',
|
||||
'nonScalingStroke',
|
||||
'class',
|
||||
]);
|
||||
|
||||
@@ -23,6 +23,10 @@ export interface LucideProps extends SVGAttributes {
|
||||
height?: string | number;
|
||||
color?: string;
|
||||
strokeWidth?: string | number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -26,6 +27,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -84,6 +86,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -96,6 +99,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
aria-label="Air conditioning"
|
||||
/>
|
||||
));
|
||||
@@ -109,6 +113,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
// @ts-expect-error
|
||||
title="Air conditioning"
|
||||
/>
|
||||
@@ -123,6 +128,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
>
|
||||
<title>Some title</title>
|
||||
</Icon>
|
||||
@@ -137,6 +143,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
aria-hidden={false}
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -9,7 +9,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
viewBox="0 0 24 24"
|
||||
width="48"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@@ -80,3 +80,44 @@ exports[`Using lucide icon components > should render a component 1`] = `
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using lucide icon components > should scale the strokeWidth when absoluteStrokeWidth is set 1`] = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="48"
|
||||
height="48"
|
||||
viewbox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="red"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-grid-3x3 lucide-grid lucide-grid-3-x-3 lucide-icon"
|
||||
aria-hidden="true"
|
||||
data-testid="grid-icon"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
x="3"
|
||||
y="3"
|
||||
rx="2"
|
||||
key="afitv7"
|
||||
>
|
||||
</rect>
|
||||
<path d="M3 9h18"
|
||||
key="1pudct"
|
||||
>
|
||||
</path>
|
||||
<path d="M3 15h18"
|
||||
key="5xshup"
|
||||
>
|
||||
</path>
|
||||
<path d="M9 3v18"
|
||||
key="fh3hqa"
|
||||
>
|
||||
</path>
|
||||
<path d="M15 3v18"
|
||||
key="14nvp0"
|
||||
>
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
@@ -64,6 +64,22 @@ describe('Using LucideProvider', () => {
|
||||
expect(container.firstElementChild).toHaveAttribute('height', '48');
|
||||
});
|
||||
|
||||
it('should render the icon with LucideProvider and custom absoluteStrokeWidth', () => {
|
||||
const { container } = render(() => (
|
||||
<LucideProvider
|
||||
size={48}
|
||||
color="red"
|
||||
absoluteStrokeWidth
|
||||
>
|
||||
<House />
|
||||
</LucideProvider>
|
||||
));
|
||||
|
||||
const IconComponent = container.firstElementChild;
|
||||
|
||||
expect(IconComponent).toHaveAttribute('stroke-width', '1');
|
||||
});
|
||||
|
||||
it("should override the provider's global props when passing props to the icon", () => {
|
||||
const { container } = render(() => (
|
||||
<LucideProvider
|
||||
|
||||
@@ -57,6 +57,28 @@ describe('Using lucide icon components', () => {
|
||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
|
||||
});
|
||||
|
||||
it('should scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||
const testId = 'grid-icon';
|
||||
const { container, getByTestId } = render(() => (
|
||||
<Grid
|
||||
data-testid={testId}
|
||||
size={48}
|
||||
color="red"
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
));
|
||||
|
||||
const { attributes } = getByTestId(testId) as unknown as {
|
||||
attributes: Record<string, { value: string }>;
|
||||
};
|
||||
expect(attributes.stroke.value).toBe('red');
|
||||
expect(attributes.width.value).toBe('48');
|
||||
expect(attributes.height.value).toBe('48');
|
||||
expect(attributes['stroke-width'].value).toBe('1');
|
||||
|
||||
expect(container.innerHTML).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should add all classes to the element', () => {
|
||||
const testClass = 'my-class';
|
||||
const { container } = render(() => <Droplet class={testClass} />);
|
||||
|
||||
@@ -30,6 +30,12 @@ function buildLucideIconNode(icon: LucideIconData, params: LucideBuildParams = {
|
||||
? mergeClasses(...classNamesFromClassName)
|
||||
: mergeClasses('lucide', ...iconClassNames, ...classNamesFromClassName);
|
||||
|
||||
const calculatedStrokeWidth = params.absoluteStrokeWidth
|
||||
? (Number(params.strokeWidth ?? defaultAttributes['stroke-width']) *
|
||||
Number(icon.size ?? icon.width ?? defaultAttributes['width'])) /
|
||||
Number(params.size ?? params.width ?? defaultAttributes['width'])
|
||||
: (params.strokeWidth ?? defaultAttributes['stroke-width']);
|
||||
|
||||
const attributes = {
|
||||
...Object.entries(defaultAttributes).reduce((attrs, [attrName, value]) => {
|
||||
attrs[getAttributeName(attrName)] = value;
|
||||
@@ -52,7 +58,7 @@ function buildLucideIconNode(icon: LucideIconData, params: LucideBuildParams = {
|
||||
isDefined(params.height) && {
|
||||
[getAttributeName('height')]: params.height,
|
||||
}),
|
||||
[getAttributeName('stroke-width')]: params.strokeWidth ?? defaultAttributes['stroke-width'],
|
||||
[getAttributeName('stroke-width')]: calculatedStrokeWidth,
|
||||
...(className && {
|
||||
[getAttributeName('class')]: className,
|
||||
}),
|
||||
|
||||
@@ -38,6 +38,11 @@ export type LucideBuildParams<TProps extends Record<string, unknown> = SVGProps>
|
||||
* The stroke width.
|
||||
*/
|
||||
strokeWidth?: string | number;
|
||||
/**
|
||||
* Whether to use absolute stroke width.
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
/**
|
||||
* Adds [`vector-effect="non-scaling-stroke"`](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/vector-effect) to child elements.
|
||||
*/
|
||||
|
||||
@@ -24,6 +24,7 @@ const LOCAL_PROP_KEYS = [
|
||||
'class',
|
||||
'icon',
|
||||
'iconNode',
|
||||
'absoluteStrokeWidth',
|
||||
'nonScalingStroke',
|
||||
] as const;
|
||||
|
||||
@@ -47,6 +48,7 @@ const Icon = (props: LucideProps & IconProps) => {
|
||||
width: props.width ?? props.size ?? globalProps.size,
|
||||
height: props.height ?? props.size ?? globalProps.size,
|
||||
strokeWidth: props.strokeWidth ?? globalProps.strokeWidth,
|
||||
absoluteStrokeWidth: props.absoluteStrokeWidth ?? globalProps.absoluteStrokeWidth,
|
||||
nonScalingStroke: props.nonScalingStroke ?? globalProps.nonScalingStroke,
|
||||
className: mergeClasses('lucide-icon', globalProps.class, props.class),
|
||||
hasA11yProp: Boolean(props.children) || hasA11yProp(rest()),
|
||||
|
||||
@@ -4,12 +4,17 @@ export const LucideContext = createContext<{
|
||||
size?: number;
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
class?: string;
|
||||
}>({
|
||||
size: 24,
|
||||
color: 'currentColor',
|
||||
strokeWidth: 2,
|
||||
absoluteStrokeWidth: false,
|
||||
nonScalingStroke: false,
|
||||
class: '',
|
||||
});
|
||||
@@ -19,6 +24,10 @@ interface LucideProviderProps {
|
||||
size?: number;
|
||||
color?: string;
|
||||
strokeWidth?: number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@ export interface LucideProps extends SVGAttributes {
|
||||
height?: string | number;
|
||||
color?: string;
|
||||
strokeWidth?: string | number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -26,6 +27,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -85,6 +87,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -97,6 +100,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
aria-label="Air conditioning"
|
||||
/>
|
||||
));
|
||||
@@ -110,6 +114,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
// @ts-expect-error
|
||||
title="Air conditioning"
|
||||
/>
|
||||
@@ -124,6 +129,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
>
|
||||
<title>Some title</title>
|
||||
</Icon>
|
||||
@@ -138,6 +144,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode={airVent}
|
||||
size={48}
|
||||
stroke="red"
|
||||
absoluteStrokeWidth
|
||||
aria-hidden="false"
|
||||
/>
|
||||
));
|
||||
|
||||
@@ -9,7 +9,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
viewBox="0 0 24 24"
|
||||
width="48"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
@@ -80,3 +80,44 @@ exports[`Using lucide icon components > should render a component 1`] = `
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`Using lucide icon components > should scale the strokeWidth when absoluteStrokeWidth is set 1`] = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="48"
|
||||
height="48"
|
||||
viewbox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="red"
|
||||
stroke-width="1"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-grid-3x3 lucide-grid lucide-grid-3-x-3 lucide-icon"
|
||||
aria-hidden="true"
|
||||
data-testid="grid-icon"
|
||||
>
|
||||
<rect width="18"
|
||||
height="18"
|
||||
x="3"
|
||||
y="3"
|
||||
rx="2"
|
||||
key="afitv7"
|
||||
>
|
||||
</rect>
|
||||
<path d="M3 9h18"
|
||||
key="1pudct"
|
||||
>
|
||||
</path>
|
||||
<path d="M3 15h18"
|
||||
key="5xshup"
|
||||
>
|
||||
</path>
|
||||
<path d="M9 3v18"
|
||||
key="fh3hqa"
|
||||
>
|
||||
</path>
|
||||
<path d="M15 3v18"
|
||||
key="14nvp0"
|
||||
>
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
@@ -65,6 +65,22 @@ describe('Using LucideProvider', () => {
|
||||
expect(container.firstElementChild).toHaveAttribute('height', '48');
|
||||
});
|
||||
|
||||
it('should render the icon with LucideProvider and custom absoluteStrokeWidth', () => {
|
||||
const { container } = render(() => (
|
||||
<LucideProvider
|
||||
size={48}
|
||||
color="red"
|
||||
absoluteStrokeWidth
|
||||
>
|
||||
<House />
|
||||
</LucideProvider>
|
||||
));
|
||||
|
||||
const IconComponent = container.firstElementChild;
|
||||
|
||||
expect(IconComponent).toHaveAttribute('stroke-width', '1');
|
||||
});
|
||||
|
||||
it("should override the provider's global props when passing props to the icon", () => {
|
||||
const { container } = render(() => (
|
||||
<LucideProvider
|
||||
|
||||
@@ -57,6 +57,28 @@ describe('Using lucide icon components', () => {
|
||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
|
||||
});
|
||||
|
||||
it('should scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||
const testId = 'grid-icon';
|
||||
const { container, getByTestId } = render(() => (
|
||||
<Grid
|
||||
data-testid={testId}
|
||||
size={48}
|
||||
color="red"
|
||||
absoluteStrokeWidth
|
||||
/>
|
||||
));
|
||||
|
||||
const { attributes } = getByTestId(testId) as unknown as {
|
||||
attributes: Record<string, { value: string }>;
|
||||
};
|
||||
expect(attributes.stroke.value).toBe('red');
|
||||
expect(attributes.width.value).toBe('48');
|
||||
expect(attributes.height.value).toBe('48');
|
||||
expect(attributes['stroke-width'].value).toBe('1');
|
||||
|
||||
expect(container.innerHTML).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should add all classes to the element', () => {
|
||||
const testClass = 'my-class';
|
||||
const { container } = render(() => <Droplet class={testClass} />);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
width = size,
|
||||
height = size,
|
||||
strokeWidth = globalProps.strokeWidth ?? 2,
|
||||
absoluteStrokeWidth = globalProps.absoluteStrokeWidth ?? false,
|
||||
nonScalingStroke = globalProps.nonScalingStroke ?? false,
|
||||
iconNode = [],
|
||||
icon = {
|
||||
@@ -37,6 +38,7 @@
|
||||
width,
|
||||
height,
|
||||
strokeWidth,
|
||||
absoluteStrokeWidth,
|
||||
nonScalingStroke,
|
||||
// @TODO: maybe drop the extra `lucide-icon` class altogether.
|
||||
className: mergeClasses('lucide-icon', globalProps.class),
|
||||
|
||||
@@ -6,6 +6,10 @@ export interface LucideGlobalContext {
|
||||
color?: string;
|
||||
size?: number;
|
||||
strokeWidth?: number;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ export type LucideProps = Attrs & {
|
||||
color?: string;
|
||||
size?: number | string;
|
||||
strokeWidth?: number | string;
|
||||
/**
|
||||
* @deprecated Use `nonScalingStroke` instead.
|
||||
*/
|
||||
absoluteStrokeWidth?: boolean;
|
||||
nonScalingStroke?: boolean;
|
||||
children?: Snippet;
|
||||
title?: string;
|
||||
|
||||
@@ -12,6 +12,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode: airVent,
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -24,6 +25,7 @@ describe('Using Icon Component', () => {
|
||||
iconNode: airVent,
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -38,6 +40,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode: airVent,
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -50,6 +53,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode: airVent,
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
'aria-label': 'Air conditioning',
|
||||
},
|
||||
});
|
||||
@@ -63,6 +67,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode: airVent,
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
title: 'Air conditioning',
|
||||
},
|
||||
});
|
||||
@@ -76,6 +81,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode: airVent,
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
'aria-label': 'Air conditioning',
|
||||
},
|
||||
});
|
||||
@@ -89,6 +95,7 @@ describe('Icon Component Accessibility', () => {
|
||||
iconNode: airVent,
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
'aria-hidden': 'false',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
stroke-width="1"
|
||||
viewBox="0 0 24 24"
|
||||
width="48"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user