mirror of
https://github.com/lucide-icons/lucide.git
synced 2025-12-16 17:27:43 +01:00
Improve formatting (#1814)
* Ignore linting for examples in docs * Formatting JSX single attribute per line * Separte `format` and `lint:format` in package.json * Bump prettier version * Run format
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import plugins, { replace } from '@lucide/rollup-plugins';
|
||||
import pkg from './package.json' assert { type: 'json' };
|
||||
import dts from "rollup-plugin-dts";
|
||||
import dts from 'rollup-plugin-dts';
|
||||
|
||||
const packageName = 'LucideVueNext';
|
||||
const outputFileName = 'lucide-vue-next';
|
||||
@@ -33,7 +33,7 @@ const bundles = [
|
||||
|
||||
const configs = bundles
|
||||
.map(({ inputs, outputDir, format, minify, preserveModules }) =>
|
||||
inputs.map(input => ({
|
||||
inputs.map((input) => ({
|
||||
input,
|
||||
plugins: plugins(pkg, minify),
|
||||
external: ['vue'],
|
||||
@@ -57,19 +57,22 @@ const configs = bundles
|
||||
)
|
||||
.flat();
|
||||
|
||||
export default [
|
||||
{
|
||||
input: inputs[0],
|
||||
output: [{
|
||||
file: `dist/${outputFileName}.d.ts`, format: "es"
|
||||
}],
|
||||
plugins: [
|
||||
dts({
|
||||
compilerOptions: {
|
||||
preserveSymlinks: false
|
||||
}
|
||||
})
|
||||
],
|
||||
},
|
||||
...configs
|
||||
];
|
||||
export default [
|
||||
{
|
||||
input: inputs[0],
|
||||
output: [
|
||||
{
|
||||
file: `dist/${outputFileName}.d.ts`,
|
||||
format: 'es',
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
dts({
|
||||
compilerOptions: {
|
||||
preserveSymlinks: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
...configs,
|
||||
];
|
||||
|
||||
@@ -4,14 +4,13 @@ import defaultAttributes from './defaultAttributes';
|
||||
|
||||
// Create interface extending SVGAttributes
|
||||
export interface SVGProps extends Partial<SVGAttributes> {
|
||||
size?: 24 | number
|
||||
strokeWidth?: number | string
|
||||
absoluteStrokeWidth?: boolean
|
||||
size?: 24 | number;
|
||||
strokeWidth?: number | string;
|
||||
absoluteStrokeWidth?: boolean;
|
||||
}
|
||||
|
||||
|
||||
export type IconNode = [elementName: string, attrs: Record<string, string>][]
|
||||
export type Icon = FunctionalComponent<SVGProps>
|
||||
export type IconNode = [elementName: string, attrs: Record<string, string>][];
|
||||
export type Icon = FunctionalComponent<SVGProps>;
|
||||
/**
|
||||
* Converts string to KebabCase
|
||||
* Copied from scripts/helper. If anyone knows how to properly import it here
|
||||
@@ -20,29 +19,31 @@ export type Icon = FunctionalComponent<SVGProps>
|
||||
* @param {string} string
|
||||
* @returns {string} A kebabized string
|
||||
*/
|
||||
export const toKebabCase = (string: string) => string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
export const toKebabCase = (string: string) =>
|
||||
string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
|
||||
const createLucideIcon = (iconName: string, iconNode: IconNode): Icon => (
|
||||
{ size, strokeWidth = 2, absoluteStrokeWidth, color, class: classes, ...props }, // props
|
||||
{ attrs, slots } // context
|
||||
const createLucideIcon =
|
||||
(iconName: string, iconNode: IconNode): Icon =>
|
||||
(
|
||||
{ size, strokeWidth = 2, absoluteStrokeWidth, color, class: classes, ...props }, // props
|
||||
{ attrs, slots }, // context
|
||||
) => {
|
||||
return h(
|
||||
'svg',
|
||||
{
|
||||
...defaultAttributes,
|
||||
width: size || defaultAttributes.width,
|
||||
height: size || defaultAttributes.height,
|
||||
stroke: color || defaultAttributes.stroke,
|
||||
'stroke-width': absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
|
||||
...attrs,
|
||||
class: ['lucide', `lucide-${toKebabCase(iconName)}`],
|
||||
...props,
|
||||
},
|
||||
[
|
||||
...iconNode.map(child => h(...child)),
|
||||
...(slots.default ? [slots.default()] : [])
|
||||
],
|
||||
);
|
||||
};
|
||||
return h(
|
||||
'svg',
|
||||
{
|
||||
...defaultAttributes,
|
||||
width: size || defaultAttributes.width,
|
||||
height: size || defaultAttributes.height,
|
||||
stroke: color || defaultAttributes.stroke,
|
||||
'stroke-width': absoluteStrokeWidth
|
||||
? (Number(strokeWidth) * 24) / Number(size)
|
||||
: strokeWidth,
|
||||
...attrs,
|
||||
class: ['lucide', `lucide-${toKebabCase(iconName)}`],
|
||||
...props,
|
||||
},
|
||||
[...iconNode.map((child) => h(...child)), ...(slots.default ? [slots.default()] : [])],
|
||||
);
|
||||
};
|
||||
|
||||
export default createLucideIcon;
|
||||
|
||||
@@ -1,94 +1,93 @@
|
||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
||||
import {render, fireEvent, cleanup } from '@testing-library/vue'
|
||||
import { Smile, Edit2, Pen } from '../src/lucide-vue-next'
|
||||
import { render, fireEvent, cleanup } from '@testing-library/vue';
|
||||
import { Smile, Edit2, Pen } from '../src/lucide-vue-next';
|
||||
|
||||
describe('Using lucide icon components', () => {
|
||||
afterEach(() => cleanup())
|
||||
afterEach(() => cleanup());
|
||||
|
||||
it('should render an component', () => {
|
||||
const { container } = render(Smile)
|
||||
const { container } = render(Smile);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should adjust the size, stroke color and stroke width', () => {
|
||||
const {container} = render(Smile, {
|
||||
const { container } = render(Smile, {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
'stroke-width': 4
|
||||
}
|
||||
})
|
||||
'stroke-width': 4,
|
||||
},
|
||||
});
|
||||
|
||||
const [icon] = document.getElementsByClassName('lucide');
|
||||
|
||||
expect(icon.getAttribute('width')).toBe('48')
|
||||
expect(icon.getAttribute('stroke')).toBe('red')
|
||||
expect(icon.getAttribute('stroke-width')).toBe('4')
|
||||
expect(icon.getAttribute('width')).toBe('48');
|
||||
expect(icon.getAttribute('stroke')).toBe('red');
|
||||
expect(icon.getAttribute('stroke-width')).toBe('4');
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
|
||||
it('should add a class to the element', () => {
|
||||
const {container} = render(Smile, {
|
||||
const { container } = render(Smile, {
|
||||
attrs: {
|
||||
class: "my-icon"
|
||||
}
|
||||
})
|
||||
class: 'my-icon',
|
||||
},
|
||||
});
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
const [icon] = document.getElementsByClassName('my-icon');
|
||||
|
||||
expect(icon).toHaveClass('my-icon')
|
||||
expect(icon).toHaveClass('lucide')
|
||||
expect(icon).toHaveClass('lucide-smile-icon')
|
||||
expect(icon).toHaveClass('my-icon');
|
||||
expect(icon).toHaveClass('lucide');
|
||||
expect(icon).toHaveClass('lucide-smile-icon');
|
||||
});
|
||||
|
||||
it('should add a style attribute to the element', () => {
|
||||
const {container} = render(Smile, {
|
||||
const { container } = render(Smile, {
|
||||
attrs: {
|
||||
style: 'position: absolute',
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
const [icon] = document.getElementsByClassName('lucide');
|
||||
|
||||
expect(icon).toHaveStyle({ position: 'absolute' })
|
||||
expect(icon).toHaveStyle({ position: 'absolute' });
|
||||
});
|
||||
|
||||
it('should call the onClick event', async () => {
|
||||
const onClick = vi.fn()
|
||||
const onClick = vi.fn();
|
||||
render(Smile, {
|
||||
attrs: {
|
||||
onClick,
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
const [icon] = document.getElementsByClassName('lucide');
|
||||
|
||||
await fireEvent.click(icon)
|
||||
await fireEvent.click(icon);
|
||||
|
||||
expect(onClick).toHaveBeenCalled()
|
||||
expect(onClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should pass children to the icon slot', () => {
|
||||
const testText = 'Hello World'
|
||||
const testText = 'Hello World';
|
||||
const template = {
|
||||
name: 'Stub',
|
||||
template: `<text>${testText}</text>`
|
||||
}
|
||||
template: `<text>${testText}</text>`,
|
||||
};
|
||||
const { getByText, container } = render(Smile, {
|
||||
slots: {
|
||||
default: template
|
||||
}
|
||||
})
|
||||
default: template,
|
||||
},
|
||||
});
|
||||
|
||||
const textElement = getByText(testText)
|
||||
const textElement = getByText(testText);
|
||||
|
||||
expect(textElement).toBeInTheDocument()
|
||||
expect(textElement).toBeInTheDocument();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -97,38 +96,38 @@ describe('Using lucide icon components', () => {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
'stroke-width': 4
|
||||
}
|
||||
})
|
||||
'stroke-width': 4,
|
||||
},
|
||||
});
|
||||
|
||||
const PenIconRenderedHTML = container.innerHTML
|
||||
const PenIconRenderedHTML = container.innerHTML;
|
||||
|
||||
cleanup()
|
||||
cleanup();
|
||||
|
||||
const { container: Edit2Container } = render(Edit2, {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
'stroke-width': 4
|
||||
}
|
||||
})
|
||||
'stroke-width': 4,
|
||||
},
|
||||
});
|
||||
|
||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML)
|
||||
})
|
||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
|
||||
});
|
||||
|
||||
it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||
render(Pen, {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true
|
||||
}
|
||||
})
|
||||
absoluteStrokeWidth: true,
|
||||
},
|
||||
});
|
||||
|
||||
const [icon] = document.getElementsByClassName('lucide');
|
||||
|
||||
expect(icon.getAttribute('width')).toBe('48')
|
||||
expect(icon.getAttribute('stroke')).toBe('red')
|
||||
expect(icon.getAttribute('stroke-width')).toBe('1')
|
||||
})
|
||||
expect(icon.getAttribute('width')).toBe('48');
|
||||
expect(icon.getAttribute('stroke')).toBe('red');
|
||||
expect(icon.getAttribute('stroke-width')).toBe('1');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,5 +12,5 @@
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"skipLibCheck": true,
|
||||
"noEmit": true,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user