mirror of
https://github.com/lucide-icons/lucide.git
synced 2026-11-12 13:38:32 +00:00
buildLucideIconForReact is the entry point both lucide-react and lucide-react-native use to build an icon, and its whole job is renaming the hyphenated SVG attributes to the spellings React expects. Nothing tested that rename directly: the other build helpers have specs in packages/icons/tests, and this one had none anywhere in the repo. The spec pins the five renames it applies, checks that attributes React already accepts are left alone, that aria-hidden stays hyphenated, that vector-effect is renamed on child nodes for a non-scaling stroke, and that a caller's own attributeNames are merged without displacing the React spellings. Verified that the spec is not vacuous: removing the class -> className entry from the rename map fails two of the five tests. Co-authored-by: Vugar Bakhishov <vugarbbakhishov-hub@users.noreply.github.com> Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
69 lines
2.6 KiB
TypeScript
69 lines
2.6 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import buildLucideIconForReact from '../src/build/buildLucideIconForReact';
|
|
import defaultReactAttributes from '../src/build/defaultReactAttributes';
|
|
import type { LucideIconData, LucideIconNode, SVGProps } from '../src/build/types';
|
|
|
|
const icon: LucideIconData = {
|
|
name: 'house',
|
|
size: 24,
|
|
node: [['path', { d: 'M0 0h1' }]],
|
|
};
|
|
|
|
const childrenOf = (node: LucideIconNode) => (node.at(2) ?? []) as LucideIconNode[];
|
|
|
|
describe('buildLucideIconForReact', () => {
|
|
it('uses the React spelling for the hyphenated SVG attributes', () => {
|
|
const [, attributes] = buildLucideIconForReact(icon);
|
|
|
|
expect(attributes).toMatchObject({
|
|
strokeWidth: defaultReactAttributes.strokeWidth,
|
|
strokeLinecap: defaultReactAttributes.strokeLinecap,
|
|
strokeLinejoin: defaultReactAttributes.strokeLinejoin,
|
|
className: 'lucide lucide-house',
|
|
});
|
|
|
|
expect(attributes).not.toHaveProperty('stroke-width');
|
|
expect(attributes).not.toHaveProperty('stroke-linecap');
|
|
expect(attributes).not.toHaveProperty('stroke-linejoin');
|
|
expect(attributes).not.toHaveProperty('class');
|
|
});
|
|
|
|
it('leaves the attributes React already accepts untouched', () => {
|
|
const [, attributes] = buildLucideIconForReact(icon);
|
|
|
|
expect(attributes).toMatchObject({
|
|
xmlns: defaultReactAttributes.xmlns,
|
|
width: defaultReactAttributes.width,
|
|
height: defaultReactAttributes.height,
|
|
viewBox: defaultReactAttributes.viewBox,
|
|
fill: defaultReactAttributes.fill,
|
|
stroke: defaultReactAttributes.stroke,
|
|
});
|
|
});
|
|
|
|
it('keeps aria-hidden hyphenated, which is how React expects it', () => {
|
|
const [, attributes] = buildLucideIconForReact(icon, { hasA11yProp: false });
|
|
|
|
expect(attributes['aria-hidden']).toBe('true');
|
|
expect(attributes).not.toHaveProperty('ariaHidden');
|
|
});
|
|
|
|
it('renames vector-effect on the child nodes for a non-scaling stroke', () => {
|
|
const children = childrenOf(buildLucideIconForReact(icon, { nonScalingStroke: true }));
|
|
const childAttributes = (children[0]?.[1] ?? {}) as SVGProps;
|
|
|
|
expect(childAttributes.vectorEffect).toBe('non-scaling-stroke');
|
|
expect(childAttributes).not.toHaveProperty('vector-effect');
|
|
});
|
|
|
|
it('merges caller attribute names but keeps its own React spellings', () => {
|
|
const [, attributes] = buildLucideIconForReact(icon, {
|
|
attributeNames: { fill: 'fillColor', class: 'cssClass' },
|
|
});
|
|
|
|
expect(attributes.fillColor).toBe(defaultReactAttributes.fill);
|
|
expect(attributes.className).toBe('lucide lucide-house');
|
|
expect(attributes).not.toHaveProperty('cssClass');
|
|
});
|
|
});
|