[Packages][Lucide] Switch to data-lucide (#1169)

* [packages][lucide] Switch to the HTML attribute data-lucide instead of icon-name

* fix tests

* Update lucide.ts

Add BC for `icon-name`.

* Update packages/lucide/src/lucide.ts

Co-authored-by: Karsa <contact@karsa.org>

---------

Co-authored-by: Karsa <karsa@karsa.org>
Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
This commit is contained in:
Karsa
2023-05-30 20:42:41 +02:00
committed by GitHub
parent 9ef9921f04
commit 17ecb92946
6 changed files with 29 additions and 19 deletions
+6 -6
View File
@@ -35,9 +35,9 @@ Here is a complete example with unpkg
```html
<!DOCTYPE html>
<body>
<i icon-name="volume-2" class="my-class"></i>
<i icon-name="x"></i>
<i icon-name="menu"></i>
<i data-lucide="volume-2" class="my-class"></i>
<i data-lucide="x"></i>
<i data-lucide="menu"></i>
<script src="https://unpkg.com/lucide@latest"></script>
<script>
@@ -49,11 +49,11 @@ Here is a complete example with unpkg
### With ESModules
To reduce bundle size, lucide is built to be fully tree-shakable.
The `createIcons` function will search for HTMLElements with the attribute `icon-name` and replace it with the svg from the given icon name.
The `createIcons` function will search for HTMLElements with the attribute `data-lucide` and replace it with the svg from the given icon name.
```html
<!-- Your HTML file -->
<i icon-name="menu"></i>
<i data-lucide="menu"></i>
```
```js
@@ -89,7 +89,7 @@ createIcons({
'stroke-width': 1,
stroke: '#333'
},
nameAttr: 'icon-name' // attribute for the icon name.
nameAttr: 'data-lucide' // attribute for the icon name.
});
```
+2 -2
View File
@@ -50,9 +50,9 @@ export interface CreateIconsOptions {
/**
* Search HTML emelemt by \`nameAttr\` property.
*
* For example if define \`<i lucide-icon="circle"></i>\`, fill by \`lucide-icon\`.
* For example if define \`<i data-lucide="circle"></i>\`, fill by \`data-lucide\`.
*
* @default 'icon-name'
* @default 'data-lucide'
*/
nameAttr?: string;
+12 -2
View File
@@ -5,7 +5,7 @@ import * as allIcons from './icons';
* Replaces all elements with matching nameAttr with the defined icons
* @param {{ icons?: object, nameAttr?: string, attrs?: object }} options
*/
const createIcons = ({ icons = {}, nameAttr = 'icon-name', attrs = {} } = {}) => {
const createIcons = ({ icons = {}, nameAttr = 'data-lucide', attrs = {} } = {}) => {
if (!Object.values(icons).length) {
throw new Error(
"Please provide an icons object.\nIf you want to use all the icons you can import it like:\n `import { createIcons, icons } from 'lucide';\nlucide.createIcons({icons});`",
@@ -17,10 +17,20 @@ const createIcons = ({ icons = {}, nameAttr = 'icon-name', attrs = {} } = {}) =>
}
const elementsToReplace = document.querySelectorAll(`[${nameAttr}]`);
Array.from(elementsToReplace).forEach((element) =>
replaceElement(element, { nameAttr, icons, attrs }),
);
/** @todo: remove this block in v1.0 */
if (nameAttr === 'data-lucide') {
const deprecatedElements = document.querySelectorAll('[icon-name]');
if (deprecatedElements.length > 0) {
console.warn('[Lucide] Some icons were found with the now deprecated icon-name attribute. These will still be replaced for backwards compatibility, but will no longer be supported in v1.0 and you should switch to data-lucide');
Array.from(deprecatedElements).forEach((element) =>
replaceElement(element, { nameAttr: 'icon-name', icons, attrs }),
);
}
}
};
export { createIcons };
+1 -1
View File
@@ -83,7 +83,7 @@ const replaceElement = (element: Element, { nameAttr, icons, attrs }: ReplaceEle
const iconAttrs = {
...iconAttributes,
'icon-name': iconName,
'data-lucide': iconName,
...attrs,
...elementAttrs,
};
@@ -1,5 +1,5 @@
// Vitest Snapshot v1
exports[`createIcons > should add custom attributes 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"black\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" icon-name=\\"volume-2\\" class=\\"lucide lucide-volume-2 icon custom-class\\"><polygon points=\\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\\"></polygon><path d=\\"M15.54 8.46a5 5 0 0 1 0 7.07\\"></path><path d=\\"M19.07 4.93a10 10 0 0 1 0 14.14\\"></path></svg>"`;
exports[`createIcons > should add custom attributes 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"black\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" data-lucide=\\"volume-2\\" class=\\"lucide lucide-volume-2 icon custom-class\\"><polygon points=\\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\\"></polygon><path d=\\"M15.54 8.46a5 5 0 0 1 0 7.07\\"></path><path d=\\"M19.07 4.93a10 10 0 0 1 0 14.14\\"></path></svg>"`;
exports[`createIcons > should read elements from DOM and replace it with icons 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\\" icon-name=\\"volume-2\\" class=\\"lucide lucide-volume-2\\"><polygon points=\\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\\"></polygon><path d=\\"M15.54 8.46a5 5 0 0 1 0 7.07\\"></path><path d=\\"M19.07 4.93a10 10 0 0 1 0 14.14\\"></path></svg>"`;
exports[`createIcons > should read elements from DOM and replace it with icons 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\\" data-lucide=\\"volume-2\\" class=\\"lucide lucide-volume-2\\"><polygon points=\\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\\"></polygon><path d=\\"M15.54 8.46a5 5 0 0 1 0 7.07\\"></path><path d=\\"M19.07 4.93a10 10 0 0 1 0 14.14\\"></path></svg>"`;
+6 -6
View File
@@ -11,7 +11,7 @@ const getOriginalSvg = (iconName) => {
const svgContent = fs.readFileSync(path.join(ICONS_DIR, `${iconName}.svg`), 'utf8');
const svgParsed = parseSync(svgContent);
svgParsed.attributes['icon-name'] = iconName;
svgParsed.attributes['data-lucide'] = iconName;
svgParsed.attributes['class'] = `lucide lucide-${iconName}`;
return stringify(svgParsed, { selfClose: false });
@@ -19,7 +19,7 @@ const getOriginalSvg = (iconName) => {
describe('createIcons', () => {
it('should read elements from DOM and replace it with icons', () => {
document.body.innerHTML = `<i icon-name="volume-2"></i>`;
document.body.innerHTML = `<i data-lucide="volume-2"></i>`;
createIcons({icons});
@@ -30,11 +30,11 @@ describe('createIcons', () => {
});
it('should customize the name attribute', () => {
document.body.innerHTML = `<i custom-name="volume-2"></i>`;
document.body.innerHTML = `<i data-custom-name="volume-2"></i>`;
createIcons({
icons,
nameAttr: 'custom-name'
nameAttr: 'data-custom-name'
});
const hasSvg = !!document.querySelector('svg');
@@ -43,7 +43,7 @@ describe('createIcons', () => {
});
it('should add custom attributes', () => {
document.body.innerHTML = `<i icon-name="volume-2" class="lucide"></i>`;
document.body.innerHTML = `<i data-lucide="volume-2" class="lucide"></i>`;
const attrs = {
class: 'lucide lucide-volume-2 icon custom-class',
@@ -67,7 +67,7 @@ describe('createIcons', () => {
});
it('should inherit elements attributes', () => {
document.body.innerHTML = `<i icon-name="sun" data-theme-switcher="light"></i>`;
document.body.innerHTML = `<i data-lucide="sun" data-theme-switcher="light"></i>`;
const attrs = {
'data-theme-switcher':'light',