mirror of
https://github.com/lucide-icons/lucide.git
synced 2025-12-17 07:57:41 +01:00
Compare commits
5 Commits
fix/fixed-
...
0.476.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6632ce8d7 | ||
|
|
a59c5de61a | ||
|
|
2bd0ae55fd | ||
|
|
3f2ad5b2a6 | ||
|
|
1250fc276d |
@@ -126,11 +126,23 @@ import { createElement, Menu } from 'lucide';
|
||||
|
||||
const menuIcon = createElement(Menu); // Returns HTMLElement (svg)
|
||||
|
||||
// set custom attributes with browser native functions
|
||||
menuIcon.setAttribute('stroke', '#333');
|
||||
menuIcon.classList.add('my-icon-class');
|
||||
// Append HTMLElement in the DOM
|
||||
const myApp = document.getElementById('app');
|
||||
myApp.appendChild(menuIcon);
|
||||
```
|
||||
|
||||
// Append HTMLElement in webpage
|
||||
#### Custom Element binding with custom attributes
|
||||
|
||||
```js
|
||||
import { createElement, Menu } from 'lucide';
|
||||
|
||||
const menuIcon = createElement(Menu, {
|
||||
class: ['my-custom-class', 'icon'],
|
||||
'stroke-width': 1,
|
||||
stroke: '#333'
|
||||
}); // Returns HTMLElement (svg)
|
||||
|
||||
// Append HTMLElement in the DOM
|
||||
const myApp = document.getElementById('app');
|
||||
myApp.appendChild(menuIcon);
|
||||
```
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M16.4 13.7A6.5 6.5 0 1 0 6.28 6.6c-1.1 3.13-.78 3.9-3.18 6.08A3 3 0 0 0 5 18c4 0 8.4-1.8 11.4-4.3" />
|
||||
<path d="m18.5 6 2.19 4.5a6.48 6.48 0 0 1-2.29 7.2C15.4 20.2 11 22 7 22a3 3 0 0 1-2.68-1.66L2.4 16.5" />
|
||||
<circle cx="12.5" cy="8.5" r="2.5" />
|
||||
<path d="M12.5 2a6.5 6.5 0 0 0-6.22 4.6c-1.1 3.13-.78 3.9-3.18 6.08A3 3 0 0 0 5 18c4 0 8.4-1.8 11.4-4.3A6.5 6.5 0 0 0 12.5 2Z" />
|
||||
<path d="m18.5 6 2.19 4.5a6.48 6.48 0 0 1 .31 2 6.49 6.49 0 0 1-2.6 5.2C15.4 20.2 11 22 7 22a3 3 0 0 1-2.68-1.66L2.4 16.5" />
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 508 B After Width: | Height: | Size: 468 B |
23
icons/shield-user.json
Normal file
23
icons/shield-user.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "../icon.schema.json",
|
||||
"contributors": [
|
||||
"sebinemeth",
|
||||
"ksk3110",
|
||||
"karsa-mistmere",
|
||||
"colebemis"
|
||||
],
|
||||
"tags": [
|
||||
"shield",
|
||||
"user",
|
||||
"admin",
|
||||
"protection",
|
||||
"protected",
|
||||
"safety",
|
||||
"guard"
|
||||
],
|
||||
"categories": [
|
||||
"account",
|
||||
"security",
|
||||
"development"
|
||||
]
|
||||
}
|
||||
15
icons/shield-user.svg
Normal file
15
icons/shield-user.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<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="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" />
|
||||
<path d="M6.376 18.91a6 6 0 0 1 11.249.003" />
|
||||
<circle cx="12" cy="11" r="4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 469 B |
@@ -1,15 +1,16 @@
|
||||
import defaultAttributes from './defaultAttributes';
|
||||
import { IconNode, SVGProps } from './types';
|
||||
|
||||
type CreateElementParams = [tag: string, attrs: SVGProps, children?: IconNode];
|
||||
type CreateSVGElementParams = [tag: string, attrs: SVGProps, children?: IconNode];
|
||||
|
||||
/**
|
||||
* Creates a new HTMLElement from icon node
|
||||
* @param {string} tag
|
||||
* @param {object} attrs
|
||||
* @param {array} children
|
||||
* @returns {HTMLElement}
|
||||
* Creates a new SVGElement
|
||||
* @param {string} tag - Tag name of the element
|
||||
* @param {object} attrs - Attributes of the element
|
||||
* @param {array} children - Children of the element
|
||||
* @returns {SVGElement}
|
||||
*/
|
||||
const createElement = ([tag, attrs, children]: CreateElementParams) => {
|
||||
const createSVGElement = ([tag, attrs, children]: CreateSVGElementParams) => {
|
||||
const element = document.createElementNS('http://www.w3.org/2000/svg', tag);
|
||||
|
||||
Object.keys(attrs).forEach((name) => {
|
||||
@@ -18,7 +19,7 @@ const createElement = ([tag, attrs, children]: CreateElementParams) => {
|
||||
|
||||
if (children?.length) {
|
||||
children.forEach((child) => {
|
||||
const childElement = createElement(child);
|
||||
const childElement = createSVGElement(child);
|
||||
|
||||
element.appendChild(childElement);
|
||||
});
|
||||
@@ -27,4 +28,20 @@ const createElement = ([tag, attrs, children]: CreateElementParams) => {
|
||||
return element;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new HTMLElement from icon node
|
||||
* @param {array} iconNode - Icon node to be converted to an element
|
||||
* @param {object} customAttrs - Custom attributes to be added to the element
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
const createElement = (iconNode: IconNode, customAttrs: SVGProps = {}) => {
|
||||
const tag = 'svg';
|
||||
const attrs = {
|
||||
...defaultAttributes,
|
||||
...customAttrs,
|
||||
};
|
||||
|
||||
return createSVGElement([tag, attrs, iconNode]);
|
||||
};
|
||||
|
||||
export default createElement;
|
||||
|
||||
@@ -98,7 +98,7 @@ const replaceElement = (element: Element, { nameAttr, icons, attrs }: ReplaceEle
|
||||
});
|
||||
}
|
||||
|
||||
const svgElement = createElement(['svg', iconAttrs, iconNode]);
|
||||
const svgElement = createElement(iconNode, iconAttrs);
|
||||
|
||||
return element.parentNode?.replaceChild(svgElement, element);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`createElement > should match the snapshot 1`] = `
|
||||
<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="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8">
|
||||
</path>
|
||||
<path d="M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z">
|
||||
</path>
|
||||
</svg>
|
||||
`;
|
||||
37
packages/lucide/tests/createElement.spec.ts
Normal file
37
packages/lucide/tests/createElement.spec.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { House, createElement } from '../src/lucide';
|
||||
import { getOriginalSvg } from './helpers';
|
||||
|
||||
describe('createElement', () => {
|
||||
it('should create SVG Element', () => {
|
||||
const HomeSVG = createElement(House);
|
||||
|
||||
expect(HomeSVG.tagName).toBe('svg');
|
||||
});
|
||||
|
||||
it('should match the snapshot', () => {
|
||||
const HomeSVG = createElement(House);
|
||||
|
||||
expect(HomeSVG.outerHTML).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should create SVG Element with attributes', () => {
|
||||
const HomeSVG = createElement(House, { fill: 'red' });
|
||||
|
||||
expect(HomeSVG.getAttribute('fill')).toBe('red');
|
||||
});
|
||||
|
||||
it('should create SVG Element with class name', () => {
|
||||
const HomeSVG = createElement(House, { class: 'icon' });
|
||||
|
||||
expect(HomeSVG.getAttribute('class')).toBe('icon');
|
||||
});
|
||||
|
||||
it('should create the correct svg element', () => {
|
||||
const HomeSVG = createElement(House);
|
||||
|
||||
const svg = getOriginalSvg('house', undefined, false);
|
||||
|
||||
expect(HomeSVG.outerHTML).toBe(svg);
|
||||
});
|
||||
});
|
||||
17
packages/lucide/tests/helpers.ts
Normal file
17
packages/lucide/tests/helpers.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { parseSync, stringify } from 'svgson';
|
||||
|
||||
const ICONS_DIR = path.resolve(__dirname, '../../../icons');
|
||||
|
||||
export const getOriginalSvg = (iconName: string, aliasName?: string, setAttrs = true) => {
|
||||
const svgContent = fs.readFileSync(path.join(ICONS_DIR, `${iconName}.svg`), 'utf8');
|
||||
const svgParsed = parseSync(svgContent);
|
||||
|
||||
if (setAttrs) {
|
||||
svgParsed.attributes['data-lucide'] = aliasName ?? iconName;
|
||||
svgParsed.attributes['class'] = `lucide lucide-${aliasName ?? iconName}`;
|
||||
}
|
||||
|
||||
return stringify(svgParsed, { selfClose: false });
|
||||
};
|
||||
@@ -1,20 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { createIcons, icons } from '../src/lucide';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { parseSync, stringify } from 'svgson';
|
||||
|
||||
const ICONS_DIR = path.resolve(__dirname, '../../../icons');
|
||||
|
||||
const getOriginalSvg = (iconName: string, aliasName?: string) => {
|
||||
const svgContent = fs.readFileSync(path.join(ICONS_DIR, `${iconName}.svg`), 'utf8');
|
||||
const svgParsed = parseSync(svgContent);
|
||||
|
||||
svgParsed.attributes['data-lucide'] = aliasName ?? iconName;
|
||||
svgParsed.attributes['class'] = `lucide lucide-${aliasName ?? iconName}`;
|
||||
|
||||
return stringify(svgParsed, { selfClose: false });
|
||||
};
|
||||
import { getOriginalSvg } from './helpers';
|
||||
|
||||
describe('createIcons', () => {
|
||||
it('should read elements from DOM and replace it with icons', () => {
|
||||
|
||||
@@ -43,12 +43,13 @@ const getImageTagsByFiles = (files, getBaseUrl, width) =>
|
||||
return `<img title="${file}" alt="${file}" ${widthAttr} src="${url}/${base64}.svg"/>`;
|
||||
});
|
||||
|
||||
const svgFiles = readSvgDirectory(ICONS_DIR).map((file) => `icons/${file}`);
|
||||
const svgFiles = await readSvgDirectory(ICONS_DIR)
|
||||
const svgFilePaths = svgFiles.map((file) => `icons/${file}`);
|
||||
|
||||
const iconsFilteredByName = (search) => svgFiles.filter((file) => file.includes(search));
|
||||
const iconsFilteredByName = (search) => svgFilePaths.filter((file) => file.includes(search));
|
||||
|
||||
const cohesionRandomImageTags = getImageTagsByFiles(
|
||||
shuffleArray(svgFiles).slice(0, changedFiles.length),
|
||||
shuffleArray(svgFilePaths).slice(0, changedFiles.length),
|
||||
() => `${BASE_URL}/stroke-width/2`,
|
||||
).join('');
|
||||
|
||||
|
||||
@@ -12,5 +12,8 @@ import path from 'path';
|
||||
export const readSvgDirectory = async (directory, fileExtension = '.svg') => {
|
||||
const directoryContents = await fs.readdir(directory);
|
||||
|
||||
console.log(directoryContents);
|
||||
|
||||
|
||||
return directoryContents.filter((file) => path.extname(file) === fileExtension);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user