mirror of
https://github.com/lucide-icons/lucide.git
synced 2026-11-10 13:18:25 +00:00
feat(@lucide/vue): Rename Vue package name to @lucide/vue (#3337)
* Remove old vue 2 package * Add @lucide/vue package * Remove old vue 2 doc * Update docs * Adjust export template * Adjust vue package! * Fix tests * Format code * Update packages/vue/src/Icon.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Adjust vue package in docs * Update deadlinks --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
name: Lucide Vue checks
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- packages/lucide-vue/**
|
||||
- packages/shared/**
|
||||
- tools/build-icons/**
|
||||
- tools/rollup-plugins/**
|
||||
- pnpm-lock.yaml
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: 'pnpm'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter @lucide/vue build
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: 'pnpm'
|
||||
node-version-file: 'package.json'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Test
|
||||
run: pnpm --filter @lucide/vue test
|
||||
@@ -55,6 +55,7 @@ jobs:
|
||||
'lucide-svelte',
|
||||
'@lucide/astro',
|
||||
'@lucide/svelte',
|
||||
'@lucide/vue',
|
||||
]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -31,20 +31,12 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-vue-next": {
|
||||
"@lucide/vue": {
|
||||
"order": 2,
|
||||
"icon": "vue-next",
|
||||
"icon": "vue",
|
||||
"docsAlias": "lucide-vue",
|
||||
"packageDirname": "vue",
|
||||
"shields": [
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/v/lucide-vue-next",
|
||||
"href": "https://www.npmjs.com/package/lucide-vue-next"
|
||||
},
|
||||
{
|
||||
"alt": "npm",
|
||||
"src": "https://img.shields.io/npm/dw/lucide-vue-next",
|
||||
"href": "https://www.npmjs.com/package/lucide-vue-next"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lucide-svelte": {
|
||||
|
||||
@@ -37,7 +37,7 @@ export default App;
|
||||
language: 'vue',
|
||||
title: 'Vue',
|
||||
code: `<script setup>
|
||||
import { $PascalCase } from 'lucide-vue-next';
|
||||
import { $PascalCase } from '@lucide/vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -74,7 +74,7 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
|
||||
},
|
||||
{
|
||||
text: 'Lucide Vue',
|
||||
link: '/guide/packages/lucide-vue-next',
|
||||
link: '/guide/packages/lucide-vue',
|
||||
},
|
||||
{
|
||||
text: 'Lucide Svelte',
|
||||
|
||||
@@ -13,9 +13,9 @@ export default {
|
||||
label: 'Lucide documentation for React',
|
||||
},
|
||||
{
|
||||
name: 'lucide-vue-next',
|
||||
name: 'lucide-vue',
|
||||
logo: '/framework-logos/vue.svg',
|
||||
label: 'Lucide documentation for Vue 3',
|
||||
label: 'Lucide documentation for Vue',
|
||||
},
|
||||
{
|
||||
name: 'lucide-svelte',
|
||||
|
||||
+10
-11
@@ -64,25 +64,24 @@ Implementation of the lucide icon library for Vue applications.
|
||||
::: code-group
|
||||
|
||||
```sh [pnpm]
|
||||
pnpm install lucide-vue-next
|
||||
pnpm install @lucide/vue
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
yarn add lucide-vue-next
|
||||
yarn add @lucide/vue
|
||||
```
|
||||
|
||||
```sh [npm]
|
||||
npm install lucide-vue-next
|
||||
npm install @lucide/vue
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
bun add lucide-vue-next
|
||||
bun add @lucide/vue
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
For more details, see the [documentation](packages/lucide-vue-next.md).
|
||||
For Vue 2 use the `lucide-vue` package.
|
||||
For more details, see the [documentation](packages/lucide-vue.md).
|
||||
|
||||
## Svelte
|
||||
|
||||
@@ -91,22 +90,22 @@ Implementation of the lucide icon library for Svelte applications.
|
||||
::: code-group
|
||||
|
||||
```sh [pnpm]
|
||||
pnpm install lucide-svelte
|
||||
pnpm add @lucide/svelte
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
yarn add lucide-svelte
|
||||
yarn add @lucide/svelte
|
||||
```
|
||||
|
||||
```sh [npm]
|
||||
npm install lucide-svelte
|
||||
npm install @lucide/svelte
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
bun add lucide-svelte
|
||||
bun add @lucide/svelte
|
||||
```
|
||||
|
||||
:::
|
||||
> `@lucide/svelte` is only for Svelte 5, for Svelte 4 use the `lucide-svelte` package.
|
||||
|
||||
For more details, see the [documentation](packages/lucide-svelte.md).
|
||||
|
||||
|
||||
@@ -21,14 +21,7 @@ This package includes the following implementations of Lucide icons:
|
||||
|
||||
SVG sprites and icon fonts include **all icons**, which can significantly increase your app's bundle size and load time.
|
||||
|
||||
For production environments, we recommend using a bundler with tree-shaking support to include only the icons you actually use. Consider using:
|
||||
|
||||
- [lucide](lucide)
|
||||
- [lucide-react](lucide-react)
|
||||
- [lucide-vue](lucide-vue)
|
||||
- [lucide-vue-next](lucide-vue-next)
|
||||
- [lucide-angular](lucide-angular)
|
||||
- [lucide-preact](lucide-preact)
|
||||
For production environments, we recommend using a bundler with tree-shaking support to include only the icons you actually use. Consider using one of the framework-specific [packages](../../packages).
|
||||
:::
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
# Lucide Vue Next
|
||||
|
||||
Implementation of the lucide icon library for Vue 3 applications.
|
||||
|
||||
## Installation
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh [pnpm]
|
||||
pnpm install lucide-vue-next
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
yarn add lucide-vue-next
|
||||
```
|
||||
|
||||
```sh [npm]
|
||||
npm install lucide-vue-next
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
bun add lucide-vue-next
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## How to use
|
||||
|
||||
Lucide is built with ES Modules, so it's completely tree-shakable.
|
||||
|
||||
Each icon can be imported as a Vue component, which renders an inline SVG Element. This way only the icons that are imported into your project are included in the final bundle. The rest of the icons are tree-shaken away.
|
||||
|
||||
### Example
|
||||
|
||||
You can pass additional props to adjust the icon.
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Camera } from 'lucide-vue-next';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Camera
|
||||
color="red"
|
||||
:size="32"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Props
|
||||
|
||||
| name | type | default |
|
||||
| ----------------------- | --------- | ------------ |
|
||||
| `size` | *number* | 24 |
|
||||
| `color` | *string* | currentColor |
|
||||
| `stroke-width` | *number* | 2 |
|
||||
| `absoluteStrokeWidth` | *boolean* | false |
|
||||
| `default-class` | *string* | lucide-icon |
|
||||
|
||||
### Applying props
|
||||
|
||||
To customize the appearance of an icon, you can pass custom properties as props directly to the component. The component accepts all SVG attributes as props, which allows flexible styling of the SVG elements. See the list of SVG Presentation Attributes on [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/Presentation).
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<Camera fill="red" />
|
||||
</template>
|
||||
```
|
||||
|
||||
## With Lucide lab or custom icons
|
||||
|
||||
[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
|
||||
|
||||
They can be used by using the `Icon` component.
|
||||
All props like regular lucide icons can be passed to adjust the icon appearance.
|
||||
|
||||
### Using the `Icon` component
|
||||
|
||||
This creates a single icon based on the iconNode passed and renders a Lucide icon component.
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Icon } from 'lucide-vue-next';
|
||||
import { baseball } from '@lucide/lab';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Icon :iconNode="baseball" />
|
||||
</template>
|
||||
```
|
||||
|
||||
## One generic icon component
|
||||
|
||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||
|
||||
::: danger
|
||||
The example below imports all ES Modules, so exercise caution when using it. Importing all icons will significantly increase the build size of the application, negatively affecting its performance. This is especially important when using bundlers like `Webpack`, `Rollup`, or `Vite`.
|
||||
:::
|
||||
|
||||
### Icon Component Example
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import * as icons from "lucide-vue-next";
|
||||
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
size: Number,
|
||||
color: String,
|
||||
strokeWidth: Number,
|
||||
defaultClass: String
|
||||
})
|
||||
|
||||
const icon = computed(() => icons[props.name]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="icon"
|
||||
:size="size"
|
||||
:color="color"
|
||||
:stroke-width="strokeWidth" :default-class="defaultClass"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
### Using the Icon Component
|
||||
|
||||
All other props listed above also work on the `Icon` Component.
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div id="app">
|
||||
<Icon name="Airplay" />
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
@@ -2,28 +2,24 @@
|
||||
|
||||
Implementation of the lucide icon library for Vue applications.
|
||||
|
||||
::: danger
|
||||
This package is deprecated. Vue 2 is EOF See [Announcement](https://v2.vuejs.org/eol/). Migrate to Vue 3.
|
||||
:::
|
||||
|
||||
## Installation
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh [pnpm]
|
||||
pnpm install lucide-vue
|
||||
pnpm install @lucide/vue
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
yarn add lucide-vue
|
||||
yarn add @lucide/vue
|
||||
```
|
||||
|
||||
```sh [npm]
|
||||
npm install lucide-vue
|
||||
npm install @lucide/vue
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
bun add lucide-vue
|
||||
bun add @lucide/vue
|
||||
```
|
||||
|
||||
:::
|
||||
@@ -36,21 +32,19 @@ Each icon can be imported as a Vue component, which renders an inline SVG Elemen
|
||||
|
||||
### Example
|
||||
|
||||
Additional props can be passed to adjust the icon:
|
||||
You can pass additional props to adjust the icon.
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<Camera color="red" :size="32" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Camera } from 'lucide-vue';
|
||||
|
||||
export default {
|
||||
name: 'My Component',
|
||||
components: { Camera }
|
||||
};
|
||||
<script setup>
|
||||
import { Camera } from '@lucide/vue';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Camera
|
||||
color="red"
|
||||
:size="32"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Props
|
||||
@@ -73,6 +67,28 @@ To customize the appearance of an icon, you can pass custom properties as props
|
||||
</template>
|
||||
```
|
||||
|
||||
## With Lucide lab or custom icons
|
||||
|
||||
[Lucide lab](https://github.com/lucide-icons/lucide-lab) is a collection of icons that are not part of the Lucide main library.
|
||||
|
||||
They can be used by using the `Icon` component.
|
||||
All props like regular lucide icons can be passed to adjust the icon appearance.
|
||||
|
||||
### Using the `Icon` component
|
||||
|
||||
This creates a single icon based on the iconNode passed and renders a Lucide icon component.
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Icon } from '@lucide/vue';
|
||||
import { baseball } from '@lucide/lab';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Icon :iconNode="baseball" />
|
||||
</template>
|
||||
```
|
||||
|
||||
## One generic icon component
|
||||
|
||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||
@@ -84,30 +100,37 @@ The example below imports all ES Modules, so exercise caution when using it. Imp
|
||||
### Icon Component Example
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<component :is="icon" />
|
||||
</template>
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import * as icons from "@lucide/vue";
|
||||
|
||||
<script>
|
||||
import * as icons from 'lucide-vue';
|
||||
const props = defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
size: Number,
|
||||
color: String,
|
||||
strokeWidth: Number,
|
||||
defaultClass: String
|
||||
})
|
||||
|
||||
export default {
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
icon() {
|
||||
return icons[this.name];
|
||||
}
|
||||
}
|
||||
};
|
||||
const icon = computed(() => icons[props.name]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="icon"
|
||||
:size="size"
|
||||
:color="color"
|
||||
:stroke-width="strokeWidth" :default-class="defaultClass"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### Using the Icon Component
|
||||
### Using the Icon Component
|
||||
|
||||
All other props listed above also work on the `Icon` Component.
|
||||
|
||||
```vue
|
||||
<template>
|
||||
|
||||
@@ -34,6 +34,11 @@
|
||||
],
|
||||
"destination": "/icons",
|
||||
"permanent": false
|
||||
},
|
||||
{
|
||||
"source": "/guide/packages/lucide-vue-next",
|
||||
"destination": "/guide/packages/lucide-vue",
|
||||
"permanent": false
|
||||
}
|
||||
],
|
||||
"headers": [
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"@lucide/rollup-plugins": "workspace:*",
|
||||
"@lucide/shared": "workspace:*",
|
||||
"@preact/preset-vite": "^2.7.0",
|
||||
"@testing-library/jest-dom": "^6.1.4",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/preact": "^3.2.3",
|
||||
"jest-serializer-html": "^7.1.0",
|
||||
"preact": "^10.19.2",
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"@lucide/rollup-plugins": "workspace:*",
|
||||
"@lucide/build-icons": "workspace:*",
|
||||
"@lucide/shared": "workspace:*",
|
||||
"@testing-library/jest-dom": "^6.1.6",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^14.1.2",
|
||||
"@types/prop-types": "^15.7.5",
|
||||
"@types/react": "^18.0.21",
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
"@lucide/build-icons": "workspace:*",
|
||||
"@lucide/rollup-plugins": "workspace:*",
|
||||
"@lucide/shared": "workspace:*",
|
||||
"@testing-library/jest-dom": "^6.1.6",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^14.1.2",
|
||||
"@types/react": "^18.2.37",
|
||||
"@vitejs/plugin-react": "^4.4.1",
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
"@lucide/shared": "workspace:*",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@solidjs/testing-library": "^0.8.10",
|
||||
"@testing-library/jest-dom": "^6.4.2",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"babel-preset-solid": "^1.8.12",
|
||||
"jest-serializer-html": "^7.1.0",
|
||||
"rollup": "^4.22.4",
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
"@lucide/helpers": "workspace:*",
|
||||
"@sveltejs/package": "^2.2.3",
|
||||
"@sveltejs/vite-plugin-svelte": "^2.4.2",
|
||||
"@testing-library/jest-dom": "^6.1.4",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/svelte": "^4.0.2",
|
||||
"@tsconfig/svelte": "^5.0.0",
|
||||
"jest-serializer-html": "^7.1.0",
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
"@lucide/build-icons": "workspace:*",
|
||||
"@lucide/rollup-plugins": "workspace:*",
|
||||
"@lucide/shared": "workspace:*",
|
||||
"@testing-library/jest-dom": "^6.1.6",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/vue": "^8.0.3",
|
||||
"@vitejs/plugin-vue": "^4.6.2",
|
||||
"@vue/test-utils": "2.4.5",
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { FunctionalComponent } from 'vue';
|
||||
import { IconNode, LucideProps } from './types';
|
||||
import Icon from './Icon';
|
||||
|
||||
// Create interface extending SVGAttributes
|
||||
var showDeprecationWarning = true;
|
||||
|
||||
/**
|
||||
* Create a Lucide icon component
|
||||
@@ -13,8 +13,15 @@ import Icon from './Icon';
|
||||
*/
|
||||
const createLucideIcon =
|
||||
(iconName: string, iconNode: IconNode): FunctionalComponent<LucideProps> =>
|
||||
(props, { slots, attrs }) =>
|
||||
h(
|
||||
(props, { slots, attrs }) => {
|
||||
if (showDeprecationWarning) {
|
||||
console.warn(
|
||||
'[lucide-vue-nuxt]: This package is renamed to `@lucide/vue`. Please update your imports to avoid potential issues in the future.',
|
||||
);
|
||||
showDeprecationWarning = false;
|
||||
}
|
||||
|
||||
return h(
|
||||
Icon,
|
||||
{
|
||||
...attrs,
|
||||
@@ -24,5 +31,6 @@ const createLucideIcon =
|
||||
},
|
||||
slots,
|
||||
);
|
||||
};
|
||||
|
||||
export default createLucideIcon;
|
||||
|
||||
@@ -12,5 +12,6 @@
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"skipLibCheck": true,
|
||||
"noEmit": true,
|
||||
"types": ["@testing-library/jest-dom"],
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { join } from 'path';
|
||||
|
||||
export default function LucideNuxtPlugin() {
|
||||
this.nuxt.hook('components:dirs', (dirs) => {
|
||||
dirs.push({
|
||||
path: join(__dirname, 'dist', 'esm', 'icons'),
|
||||
prefix: 'Icon',
|
||||
ignore: ['**/index.js'],
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export * from './aliases';
|
||||
@@ -1,66 +0,0 @@
|
||||
import { Component } from 'vue';
|
||||
import defaultAttributes from './defaultAttributes';
|
||||
import { toKebabCase } from '@lucide/shared';
|
||||
|
||||
var showDeprecationWarning = true;
|
||||
|
||||
type IconNode = [elementName: string, attrs: Record<string, string>][];
|
||||
|
||||
export default (iconName: string, iconNode: IconNode): Component => ({
|
||||
name: iconName,
|
||||
functional: true,
|
||||
props: {
|
||||
color: {
|
||||
type: String,
|
||||
default: 'currentColor',
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 24,
|
||||
},
|
||||
strokeWidth: {
|
||||
type: Number,
|
||||
default: 2,
|
||||
},
|
||||
absoluteStrokeWidth: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
defaultClass: {
|
||||
type: String,
|
||||
default: `lucide-icon lucide lucide-${toKebabCase(iconName).replace('-icon', '')}`,
|
||||
},
|
||||
},
|
||||
render(
|
||||
createElement,
|
||||
{ props: { color, size, strokeWidth, absoluteStrokeWidth, defaultClass }, data, children = [] },
|
||||
) {
|
||||
if (showDeprecationWarning) {
|
||||
console.warn(
|
||||
'[Lucide Vue] This package will be deprecated end of 2023. Please upgrade to Vue 3 and use the latest lucide package for Vue.',
|
||||
);
|
||||
showDeprecationWarning = false;
|
||||
}
|
||||
|
||||
return createElement(
|
||||
'svg',
|
||||
{
|
||||
// prettier-ignore
|
||||
class: [defaultClass, data.class, data.staticClass, data.attrs && data.attrs.class].filter(Boolean),
|
||||
style: [data.style, data.staticStyle, data.attrs && data.attrs.style].filter(Boolean),
|
||||
attrs: {
|
||||
...defaultAttributes,
|
||||
width: size,
|
||||
height: size,
|
||||
stroke: color,
|
||||
'stroke-width': absoluteStrokeWidth
|
||||
? (Number(strokeWidth) * 24) / Number(size)
|
||||
: strokeWidth,
|
||||
...data.attrs,
|
||||
},
|
||||
on: data?.on || {},
|
||||
},
|
||||
[...iconNode.map(([tag, attrs]) => createElement(String(tag), { attrs })), ...children],
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
export * from './icons';
|
||||
export * as icons from './icons';
|
||||
export * from './aliases';
|
||||
@@ -1,132 +0,0 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { render, fireEvent, cleanup } from '@testing-library/vue';
|
||||
import { Smile, Pen, Edit2 } from '../src/lucide-vue';
|
||||
import { afterEach } from 'vitest';
|
||||
import { VueClass } from '@vue/test-utils';
|
||||
|
||||
describe('Using lucide icon components', () => {
|
||||
afterEach(() => cleanup());
|
||||
|
||||
it('should render an component', () => {
|
||||
const { container } = render(Smile as VueClass<any>);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should adjust the size, stroke color and stroke width', () => {
|
||||
const { container } = render(Smile as VueClass<any>, {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
strokeWidth: 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(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should add a class to the element', () => {
|
||||
const { container } = render(Smile as VueClass<any>, {
|
||||
attrs: {
|
||||
class: 'my-icon',
|
||||
},
|
||||
});
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
const [icon] = document.getElementsByClassName('lucide');
|
||||
|
||||
expect(icon).toHaveClass('my-icon');
|
||||
expect(icon).toHaveClass('lucide-smile');
|
||||
expect(icon).toHaveClass('lucide');
|
||||
});
|
||||
|
||||
it('should add a style attribute to the element', () => {
|
||||
const { container } = render(Smile as VueClass<any>, {
|
||||
attrs: {
|
||||
style: 'position: absolute',
|
||||
},
|
||||
});
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
const [icon] = document.getElementsByClassName('lucide');
|
||||
|
||||
expect(icon).toHaveStyle({ position: 'absolute' });
|
||||
});
|
||||
|
||||
it('should call the onClick event', async () => {
|
||||
const onClick = vi.fn();
|
||||
render(Smile as VueClass<any>, {
|
||||
listeners: {
|
||||
click: onClick,
|
||||
},
|
||||
});
|
||||
|
||||
const [icon] = document.getElementsByClassName('lucide');
|
||||
|
||||
await fireEvent.click(icon);
|
||||
|
||||
expect(onClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should pass children to the icon slot', () => {
|
||||
const testText = 'Hello World';
|
||||
const template = `<text>${testText}</text>`;
|
||||
const { getByText, container } = render(Smile as VueClass<any>, {
|
||||
slots: {
|
||||
default: { template },
|
||||
},
|
||||
});
|
||||
|
||||
const textElement = getByText(testText);
|
||||
|
||||
expect(textElement).toBeInTheDocument();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the alias icon', () => {
|
||||
const { getByText, container } = render(Pen as VueClass<any>, {
|
||||
props: {
|
||||
size: '48',
|
||||
color: 'red',
|
||||
strokeWidth: '4',
|
||||
},
|
||||
});
|
||||
|
||||
const PenIconRenderedHTML = container.innerHTML;
|
||||
|
||||
cleanup();
|
||||
|
||||
const { container: Edit2Container } = render(Edit2 as VueClass<any>, {
|
||||
props: {
|
||||
size: '48',
|
||||
color: 'red',
|
||||
strokeWidth: '4',
|
||||
},
|
||||
});
|
||||
|
||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
|
||||
});
|
||||
|
||||
it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||
const { getByText, container } = render(Pen as VueClass<any>, {
|
||||
props: {
|
||||
size: '48',
|
||||
color: 'red',
|
||||
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');
|
||||
});
|
||||
});
|
||||
@@ -1 +0,0 @@
|
||||
import '@testing-library/jest-dom';
|
||||
@@ -1,19 +0,0 @@
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import vue from '@vitejs/plugin-vue2';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
transformMode: {
|
||||
web: [/\.jsx?$/],
|
||||
},
|
||||
setupFiles: './tests/setupVitest.js',
|
||||
threads: false,
|
||||
isolate: false,
|
||||
},
|
||||
resolve: {
|
||||
conditions: ['development', 'browser'],
|
||||
},
|
||||
});
|
||||
@@ -61,7 +61,7 @@
|
||||
"@lucide/helpers": "workspace:*",
|
||||
"@sveltejs/package": "^2.3.10",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||
"@testing-library/jest-dom": "^6.1.4",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/svelte": "^5.2.7",
|
||||
"@tsconfig/svelte": "^5.0.4",
|
||||
"jest-serializer-html": "^7.1.0",
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
<p align="center">
|
||||
<a href="https://github.com/lucide-icons/lucide">
|
||||
<img src="https://lucide.dev/package-logos/lucide-vue.svg" alt="Lucide icon library for Vue 2 applications." width="540">
|
||||
<img src="https://lucide.dev/package-logos/lucide-vue.svg" alt="Lucide icon library for Vue applications." width="540">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Lucide icon library for Vue 2 applications.
|
||||
Lucide icon library for Vue applications.
|
||||
</p>
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://www.npmjs.com/package/lucide-vue)
|
||||

|
||||
[](https://lucide.dev/license)
|
||||
</div>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://lucide.dev/guide/">About</a>
|
||||
·
|
||||
@@ -27,28 +20,24 @@ Lucide icon library for Vue 2 applications.
|
||||
|
||||
# Lucide Vue
|
||||
|
||||
Implementation of the lucide icon library for Vue applications.
|
||||
|
||||
> :rotating_light:
|
||||
This package is deprecated. Vue 2 is EOF See [Announcement](https://v2.vuejs.org/eol/). Migrate to Vue 3.
|
||||
:::
|
||||
Implementation of the lucide icon library for Vue 3 applications.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
pnpm add lucide-vue
|
||||
pnpm add @lucide/vue
|
||||
```
|
||||
|
||||
```sh
|
||||
npm install lucide-vue
|
||||
npm install @lucide/vue
|
||||
```
|
||||
|
||||
```sh
|
||||
yarn add lucide-vue
|
||||
yarn add @lucide/vue
|
||||
```
|
||||
|
||||
```sh
|
||||
bun add lucide-vue
|
||||
bun add @lucide/vue
|
||||
```
|
||||
|
||||
## Documentation
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
"name": "lucide-vue",
|
||||
"name": "@lucide/vue",
|
||||
"version": "0.0.1",
|
||||
"author": "Eric Fennis",
|
||||
"description": "A Lucide icon library package for Vue 2 applications.",
|
||||
"description": "A Lucide icon library package for Vue applications.",
|
||||
"license": "ISC",
|
||||
"homepage": "https://lucide.dev",
|
||||
"bugs": "https://github.com/lucide-icons/lucide/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/lucide-icons/lucide.git",
|
||||
"directory": "packages/lucide-vue"
|
||||
"directory": "packages/vue"
|
||||
},
|
||||
"keywords": [
|
||||
"Lucide",
|
||||
@@ -18,9 +18,7 @@
|
||||
"Icons",
|
||||
"Icon",
|
||||
"SVG",
|
||||
"Feather Icons",
|
||||
"Fontawesome",
|
||||
"Font Awesome"
|
||||
"Feather Icons"
|
||||
],
|
||||
"amdName": "lucide-vue",
|
||||
"source": "build/lucide-vue.js",
|
||||
@@ -28,36 +26,38 @@
|
||||
"main:umd": "dist/umd/lucide-vue.js",
|
||||
"module": "dist/esm/lucide-vue.js",
|
||||
"unpkg": "dist/umd/lucide-vue.min.js",
|
||||
"typings": "dist/lucide-vue.d.ts",
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"dist",
|
||||
"nuxt.js"
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm clean && pnpm copy:license && pnpm build:icons && pnpm build:bundles",
|
||||
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||
"clean": "rm -rf dist && rm -rf stats && rm -rf ./src/icons/*.js",
|
||||
"build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mjs --renderUniqueKey --withAliases --aliasesFileExtension=.ts --iconFileExtension=.ts --exportFileName=index.ts",
|
||||
"clean": "rm -rf dist && rm -rf ./src/icons/*.ts",
|
||||
"build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mts --renderUniqueKey --withAliases --aliasesFileExtension=.ts --iconFileExtension=.ts --exportFileName=index.ts",
|
||||
"build:bundles": "rollup -c ./rollup.config.mjs",
|
||||
"typecheck": "tsc",
|
||||
"typecheck:watch": "tsc -w",
|
||||
"test": "pnpm build:icons && vitest run",
|
||||
"test:watch": "vitest watch",
|
||||
"version": "pnpm version --git-tag-version=false"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lucide/build-icons": "workspace:*",
|
||||
"@lucide/rollup-plugins": "workspace:*",
|
||||
"@lucide/shared": "workspace:*",
|
||||
"@testing-library/jest-dom": "^6.1.4",
|
||||
"@testing-library/vue": "^5.9.0",
|
||||
"@vitejs/plugin-vue2": "2.2.0",
|
||||
"@vue/test-utils": "1.3.0",
|
||||
"rollup": "^3.29.5",
|
||||
"typescript": "^5.8.3",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/vue": "^8.1.0",
|
||||
"@vitejs/plugin-vue": "^4.6.2",
|
||||
"@vue/test-utils": "2.4.5",
|
||||
"rollup": "^4.22.4",
|
||||
"rollup-plugin-dts": "^6.1.0",
|
||||
"vite": "^6.3.4",
|
||||
"vitest": "^3.1.3",
|
||||
"vue": "2.7.14",
|
||||
"vue-template-compiler": "2.7.14"
|
||||
"vue": "^3.4.21"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^2.6.12"
|
||||
"vue": ">=3.0.1"
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import plugins, { replace } from '@lucide/rollup-plugins';
|
||||
import plugins from '@lucide/rollup-plugins';
|
||||
import pkg from './package.json' with { type: 'json' };
|
||||
import dts from 'rollup-plugin-dts';
|
||||
|
||||
const packageName = 'LucideVue';
|
||||
const packageName = '@lucide/vue';
|
||||
const outputFileName = 'lucide-vue';
|
||||
const outputDir = 'dist';
|
||||
const inputs = ['src/lucide-vue.ts'];
|
||||
@@ -57,4 +58,54 @@ const configs = bundles
|
||||
)
|
||||
.flat();
|
||||
|
||||
export default configs;
|
||||
export default [
|
||||
{
|
||||
input: inputs[0],
|
||||
output: [
|
||||
{
|
||||
file: `dist/${outputFileName}.d.ts`,
|
||||
format: 'es',
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
dts({
|
||||
compilerOptions: {
|
||||
preserveSymlinks: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: `src/${outputFileName}.suffixed.ts`,
|
||||
output: [
|
||||
{
|
||||
file: `dist/${outputFileName}.suffixed.d.ts`,
|
||||
format: 'es',
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
dts({
|
||||
compilerOptions: {
|
||||
preserveSymlinks: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: `src/${outputFileName}.prefixed.ts`,
|
||||
output: [
|
||||
{
|
||||
file: `dist/${outputFileName}.prefixed.d.ts`,
|
||||
format: 'es',
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
dts({
|
||||
compilerOptions: {
|
||||
preserveSymlinks: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
...configs,
|
||||
];
|
||||
+10
-7
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import base64SVG from '@lucide/build-icons/utils/base64SVG.mjs';
|
||||
import base64SVG from '@lucide/build-icons/utils/base64SVG';
|
||||
import defineExportTemplate from '@lucide/build-icons/utils/defineExportTemplate';
|
||||
|
||||
export default async ({
|
||||
export default defineExportTemplate(async({
|
||||
componentName,
|
||||
iconName,
|
||||
children,
|
||||
@@ -14,20 +14,23 @@ export default async ({
|
||||
|
||||
return `
|
||||
import createLucideIcon from '../createLucideIcon';
|
||||
import { IconNode } from '../types';
|
||||
|
||||
export const __iconNode: IconNode = ${JSON.stringify(children)}
|
||||
|
||||
/**
|
||||
* @component @name ${componentName}
|
||||
* @description Lucide SVG icon component, renders SVG Element with children.
|
||||
*
|
||||
* @preview  - https://lucide.dev/icons/${iconName}
|
||||
* @see https://lucide.dev/guide/packages/lucide-vue - Documentation
|
||||
* @see https://lucide.dev/guide/packages/lucide-react - Documentation
|
||||
*
|
||||
* @param {Object} props - Lucide icons props and any valid SVG attribute
|
||||
* @returns {Component} Vue Component
|
||||
* @returns {JSX.Element} JSX Element
|
||||
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
||||
*/
|
||||
const ${componentName} = createLucideIcon('${componentName}Icon', ${JSON.stringify(children)});
|
||||
const ${componentName} = createLucideIcon('${iconName}', __iconNode);
|
||||
|
||||
export default ${componentName};
|
||||
`;
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,54 @@
|
||||
import { type FunctionalComponent, h } from 'vue';
|
||||
import { mergeClasses, toKebabCase, toPascalCase, isEmptyString } from '@lucide/shared';
|
||||
import defaultAttributes from './defaultAttributes';
|
||||
import { IconNode, LucideProps } from './types';
|
||||
|
||||
interface IconProps {
|
||||
iconNode: IconNode;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const Icon: FunctionalComponent<LucideProps & IconProps> = (
|
||||
{
|
||||
name,
|
||||
iconNode,
|
||||
absoluteStrokeWidth,
|
||||
'absolute-stroke-width': absoluteStrokeWidthKebabCase,
|
||||
strokeWidth,
|
||||
'stroke-width': strokeWidthKebabCase,
|
||||
size = defaultAttributes.width,
|
||||
color = defaultAttributes.stroke,
|
||||
...props
|
||||
},
|
||||
{ slots },
|
||||
) => {
|
||||
return h(
|
||||
'svg',
|
||||
{
|
||||
...defaultAttributes,
|
||||
...props,
|
||||
width: size,
|
||||
height: size,
|
||||
stroke: color,
|
||||
'stroke-width':
|
||||
isEmptyString(absoluteStrokeWidth) ||
|
||||
isEmptyString(absoluteStrokeWidthKebabCase) ||
|
||||
absoluteStrokeWidth === true ||
|
||||
absoluteStrokeWidthKebabCase === true
|
||||
? (Number(strokeWidth || strokeWidthKebabCase || defaultAttributes['stroke-width']) *
|
||||
24) /
|
||||
Number(size)
|
||||
: strokeWidth || strokeWidthKebabCase || defaultAttributes['stroke-width'],
|
||||
class: mergeClasses(
|
||||
'lucide',
|
||||
props.class,
|
||||
...(name
|
||||
? [`lucide-${toKebabCase(toPascalCase(name))}-icon`, `lucide-${toKebabCase(name)}`]
|
||||
: ['lucide-icon']),
|
||||
),
|
||||
},
|
||||
[...iconNode.map((child) => h(...child)), ...(slots.default ? [slots.default()] : [])],
|
||||
);
|
||||
};
|
||||
|
||||
export default Icon;
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './aliases';
|
||||
export * from './prefixed';
|
||||
export * from './suffixed';
|
||||
@@ -0,0 +1,28 @@
|
||||
import { h } from 'vue';
|
||||
import type { FunctionalComponent } from 'vue';
|
||||
import { IconNode, LucideProps } from './types';
|
||||
import Icon from './Icon';
|
||||
|
||||
// Create interface extending SVGAttributes
|
||||
|
||||
/**
|
||||
* Create a Lucide icon component
|
||||
* @param {string} iconName
|
||||
* @param {array} iconNode
|
||||
* @returns {FunctionalComponent} LucideIcon
|
||||
*/
|
||||
const createLucideIcon =
|
||||
(iconName: string, iconNode: IconNode): FunctionalComponent<LucideProps> =>
|
||||
(props, { slots, attrs }) =>
|
||||
h(
|
||||
Icon,
|
||||
{
|
||||
...attrs,
|
||||
...props,
|
||||
iconNode,
|
||||
name: iconName,
|
||||
},
|
||||
slots,
|
||||
);
|
||||
|
||||
export default createLucideIcon;
|
||||
+1
-3
@@ -1,4 +1,4 @@
|
||||
const defaultAttributes = {
|
||||
export default {
|
||||
xmlns: 'http://www.w3.org/2000/svg',
|
||||
width: 24,
|
||||
height: 24,
|
||||
@@ -9,5 +9,3 @@ const defaultAttributes = {
|
||||
'stroke-linecap': 'round',
|
||||
'stroke-linejoin': 'round',
|
||||
};
|
||||
|
||||
export default defaultAttributes;
|
||||
@@ -0,0 +1,6 @@
|
||||
export * as icons from './icons';
|
||||
export * from './aliases/prefixed';
|
||||
export * from './types';
|
||||
|
||||
export { default as createLucideIcon } from './createLucideIcon';
|
||||
export { default as Icon } from './Icon';
|
||||
@@ -0,0 +1,6 @@
|
||||
export * as icons from './icons';
|
||||
export * from './aliases/suffixed';
|
||||
export * from './types';
|
||||
|
||||
export { default as createLucideIcon } from './createLucideIcon';
|
||||
export { default as Icon } from './Icon';
|
||||
@@ -0,0 +1,7 @@
|
||||
export * from './icons';
|
||||
export * as icons from './icons';
|
||||
export * from './aliases';
|
||||
export * from './types';
|
||||
|
||||
export { default as createLucideIcon } from './createLucideIcon';
|
||||
export { default as Icon } from './Icon';
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { FunctionalComponent, SVGAttributes } from 'vue';
|
||||
|
||||
export interface LucideProps extends Partial<SVGAttributes> {
|
||||
size?: 24 | number;
|
||||
strokeWidth?: number | string;
|
||||
absoluteStrokeWidth?: boolean;
|
||||
}
|
||||
|
||||
export type IconNode = [elementName: string, attrs: Record<string, string>][];
|
||||
export type LucideIcon = FunctionalComponent<LucideProps>;
|
||||
|
||||
// Legacy exports
|
||||
export type SVGProps = LucideProps;
|
||||
@@ -0,0 +1,35 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { render } from '@testing-library/vue';
|
||||
|
||||
import { airVent } from './testIconNodes';
|
||||
import { Icon } from '../src/lucide-vue';
|
||||
|
||||
describe('Using Icon Component', () => {
|
||||
it('should render icon based on a iconNode', async () => {
|
||||
const { container } = render(Icon, {
|
||||
props: {
|
||||
iconNode: airVent,
|
||||
name: 'AirVent',
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(container.firstChild).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render icon and match snapshot', async () => {
|
||||
const { container } = render(Icon, {
|
||||
props: {
|
||||
iconNode: airVent,
|
||||
name: 'AirVent',
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Using Icon Component > should render icon and match snapshot 1`] = `
|
||||
<svg
|
||||
class="lucide lucide-air-vent-icon lucide-air-vent"
|
||||
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="M6 12H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"
|
||||
/>
|
||||
<path
|
||||
d="M6 8h12"
|
||||
/>
|
||||
<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"
|
||||
/>
|
||||
<path
|
||||
d="M6.6 15.6A2 2 0 1 0 10 17v-5"
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
@@ -0,0 +1,197 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Using lucide icon components > should add a class to the element 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide lucide-smile-icon lucide-smile my-icon"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
/>
|
||||
<path
|
||||
d="M8 14s1.5 2 4 2 4-2 4-2"
|
||||
/>
|
||||
<line
|
||||
x1="9"
|
||||
x2="9.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
<line
|
||||
x1="15"
|
||||
x2="15.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Using lucide icon components > should add a style attribute to the element 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
style="position: absolute;"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
/>
|
||||
<path
|
||||
d="M8 14s1.5 2 4 2 4-2 4-2"
|
||||
/>
|
||||
<line
|
||||
x1="9"
|
||||
x2="9.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
<line
|
||||
x1="15"
|
||||
x2="15.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Using lucide icon components > should adjust the size, stroke color and stroke width 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="48"
|
||||
stroke="red"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="4"
|
||||
viewBox="0 0 24 24"
|
||||
width="48"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
/>
|
||||
<path
|
||||
d="M8 14s1.5 2 4 2 4-2 4-2"
|
||||
/>
|
||||
<line
|
||||
x1="9"
|
||||
x2="9.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
<line
|
||||
x1="15"
|
||||
x2="15.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Using lucide icon components > should pass children to the icon slot 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
/>
|
||||
<path
|
||||
d="M8 14s1.5 2 4 2 4-2 4-2"
|
||||
/>
|
||||
<line
|
||||
x1="9"
|
||||
x2="9.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
<line
|
||||
x1="15"
|
||||
x2="15.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
|
||||
<text>
|
||||
Hello World
|
||||
</text>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Using lucide icon components > should render an component 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
/>
|
||||
<path
|
||||
d="M8 14s1.5 2 4 2 4-2 4-2"
|
||||
/>
|
||||
<line
|
||||
x1="9"
|
||||
x2="9.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
<line
|
||||
x1="15"
|
||||
x2="15.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
+8
-26
@@ -3,7 +3,7 @@
|
||||
exports[`Using lucide icon components > should add a class to the element 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide-icon lucide lucide-smile my-icon"
|
||||
class="lucide my-icon lucide-smile-icon lucide-smile my-icon"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
@@ -17,22 +17,18 @@ exports[`Using lucide icon components > should add a class to the element 1`] =
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
key="1mglay"
|
||||
r="10"
|
||||
/>
|
||||
<path
|
||||
d="M8 14s1.5 2 4 2 4-2 4-2"
|
||||
key="1y1vjs"
|
||||
/>
|
||||
<line
|
||||
key="yxxnd0"
|
||||
x1="9"
|
||||
x2="9.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
<line
|
||||
key="1p4y9e"
|
||||
x1="15"
|
||||
x2="15.01"
|
||||
y1="9"
|
||||
@@ -45,14 +41,14 @@ exports[`Using lucide icon components > should add a class to the element 1`] =
|
||||
exports[`Using lucide icon components > should add a style attribute to the element 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide-icon lucide lucide-smile"
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
style="position: absolute"
|
||||
style="position: absolute;"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -60,22 +56,18 @@ exports[`Using lucide icon components > should add a style attribute to the elem
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
key="1mglay"
|
||||
r="10"
|
||||
/>
|
||||
<path
|
||||
d="M8 14s1.5 2 4 2 4-2 4-2"
|
||||
key="1y1vjs"
|
||||
/>
|
||||
<line
|
||||
key="yxxnd0"
|
||||
x1="9"
|
||||
x2="9.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
<line
|
||||
key="1p4y9e"
|
||||
x1="15"
|
||||
x2="15.01"
|
||||
y1="9"
|
||||
@@ -88,7 +80,7 @@ exports[`Using lucide icon components > should add a style attribute to the elem
|
||||
exports[`Using lucide icon components > should adjust the size, stroke color and stroke width 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide-icon lucide lucide-smile"
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="48"
|
||||
stroke="red"
|
||||
@@ -102,22 +94,18 @@ exports[`Using lucide icon components > should adjust the size, stroke color and
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
key="1mglay"
|
||||
r="10"
|
||||
/>
|
||||
<path
|
||||
d="M8 14s1.5 2 4 2 4-2 4-2"
|
||||
key="1y1vjs"
|
||||
/>
|
||||
<line
|
||||
key="yxxnd0"
|
||||
x1="9"
|
||||
x2="9.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
<line
|
||||
key="1p4y9e"
|
||||
x1="15"
|
||||
x2="15.01"
|
||||
y1="9"
|
||||
@@ -130,7 +118,7 @@ exports[`Using lucide icon components > should adjust the size, stroke color and
|
||||
exports[`Using lucide icon components > should pass children to the icon slot 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide-icon lucide lucide-smile"
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
@@ -144,30 +132,28 @@ exports[`Using lucide icon components > should pass children to the icon slot 1`
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
key="1mglay"
|
||||
r="10"
|
||||
/>
|
||||
<path
|
||||
d="M8 14s1.5 2 4 2 4-2 4-2"
|
||||
key="1y1vjs"
|
||||
/>
|
||||
<line
|
||||
key="yxxnd0"
|
||||
x1="9"
|
||||
x2="9.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
<line
|
||||
key="1p4y9e"
|
||||
x1="15"
|
||||
x2="15.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
|
||||
<text>
|
||||
Hello World
|
||||
</text>
|
||||
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
@@ -175,7 +161,7 @@ exports[`Using lucide icon components > should pass children to the icon slot 1`
|
||||
exports[`Using lucide icon components > should render an component 1`] = `
|
||||
<div>
|
||||
<svg
|
||||
class="lucide-icon lucide lucide-smile"
|
||||
class="lucide lucide-smile-icon lucide-smile"
|
||||
fill="none"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
@@ -189,22 +175,18 @@ exports[`Using lucide icon components > should render an component 1`] = `
|
||||
<circle
|
||||
cx="12"
|
||||
cy="12"
|
||||
key="1mglay"
|
||||
r="10"
|
||||
/>
|
||||
<path
|
||||
d="M8 14s1.5 2 4 2 4-2 4-2"
|
||||
key="1y1vjs"
|
||||
/>
|
||||
<line
|
||||
key="yxxnd0"
|
||||
x1="9"
|
||||
x2="9.01"
|
||||
y1="9"
|
||||
y2="9"
|
||||
/>
|
||||
<line
|
||||
key="1p4y9e"
|
||||
x1="15"
|
||||
x2="15.01"
|
||||
y1="9"
|
||||
@@ -0,0 +1,183 @@
|
||||
import { describe, it, expect, vi, afterEach } from 'vitest';
|
||||
import { render, fireEvent, cleanup } from '@testing-library/vue';
|
||||
import { Smile, Edit2, Pen } from '../src/lucide-vue';
|
||||
import defaultAttributes from '../src/defaultAttributes';
|
||||
|
||||
describe('Using lucide icon components', () => {
|
||||
afterEach(() => cleanup());
|
||||
|
||||
it('should render an component', () => {
|
||||
const { container } = render(Smile);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the icon with the default attributes', () => {
|
||||
const { container } = render(Smile);
|
||||
|
||||
const SVGElement = container.firstElementChild;
|
||||
|
||||
expect(SVGElement).toHaveAttribute('xmlns', defaultAttributes.xmlns);
|
||||
expect(SVGElement).toHaveAttribute('width', String(defaultAttributes.width));
|
||||
expect(SVGElement).toHaveAttribute('height', String(defaultAttributes.height));
|
||||
expect(SVGElement).toHaveAttribute('viewBox', defaultAttributes.viewBox);
|
||||
expect(SVGElement).toHaveAttribute('fill', defaultAttributes.fill);
|
||||
expect(SVGElement).toHaveAttribute('stroke', defaultAttributes.stroke);
|
||||
expect(SVGElement).toHaveAttribute('stroke-width', String(defaultAttributes['stroke-width']));
|
||||
expect(SVGElement).toHaveAttribute('stroke-linecap', defaultAttributes['stroke-linecap']);
|
||||
expect(SVGElement).toHaveAttribute('stroke-linejoin', defaultAttributes['stroke-linejoin']);
|
||||
});
|
||||
|
||||
it('should adjust the size, stroke color and stroke width', () => {
|
||||
const { container } = render(Smile, {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
'stroke-width': 4,
|
||||
},
|
||||
});
|
||||
|
||||
const SVGElement = container.firstElementChild;
|
||||
|
||||
expect(SVGElement).toHaveAttribute('width', '48');
|
||||
expect(SVGElement).toHaveAttribute('stroke', 'red');
|
||||
expect(SVGElement).toHaveAttribute('stroke-width', '4');
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should add a class to the element', () => {
|
||||
const { container } = render(Smile, {
|
||||
attrs: {
|
||||
class: 'my-icon',
|
||||
},
|
||||
});
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
const icon = container.firstElementChild;
|
||||
|
||||
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, {
|
||||
attrs: {
|
||||
style: 'position: absolute',
|
||||
},
|
||||
});
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
|
||||
const icon = container.firstElementChild;
|
||||
|
||||
expect(icon).toHaveStyle({ position: 'absolute' });
|
||||
});
|
||||
|
||||
it('should call the onClick event', async () => {
|
||||
const onClick = vi.fn();
|
||||
const { container } = render(Smile, {
|
||||
attrs: {
|
||||
onClick,
|
||||
},
|
||||
});
|
||||
|
||||
const icon = container.firstElementChild;
|
||||
|
||||
await fireEvent.click(icon);
|
||||
|
||||
expect(onClick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should pass children to the icon slot', () => {
|
||||
const testText = 'Hello World';
|
||||
const template = {
|
||||
name: 'Stub',
|
||||
template: `<text>${testText}</text>`,
|
||||
};
|
||||
const { getByText, container } = render(Smile, {
|
||||
slots: {
|
||||
default: template,
|
||||
},
|
||||
});
|
||||
|
||||
const textElement = getByText(testText);
|
||||
|
||||
expect(textElement).toBeInTheDocument();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the alias icon', () => {
|
||||
const { container } = render(Pen, {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
'stroke-width': 4,
|
||||
},
|
||||
});
|
||||
|
||||
const PenIconRenderedHTML = container.innerHTML;
|
||||
|
||||
cleanup();
|
||||
|
||||
const { container: Edit2Container } = render(Edit2, {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
'stroke-width': 4,
|
||||
},
|
||||
});
|
||||
|
||||
expect(PenIconRenderedHTML).toBe(Edit2Container.innerHTML);
|
||||
});
|
||||
|
||||
it('should not scale the strokeWidth when absoluteStrokeWidth is set', () => {
|
||||
const { container } = render(Pen, {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: true,
|
||||
},
|
||||
});
|
||||
|
||||
const icon = container.firstElementChild;
|
||||
|
||||
expect(icon).toHaveAttribute('width', '48');
|
||||
expect(icon).toHaveAttribute('stroke', 'red');
|
||||
expect(icon).toHaveAttribute('stroke-width', '1');
|
||||
});
|
||||
|
||||
it('should not scale the strokeWidth when absoluteStrokeWidth is as empty value attribute', () => {
|
||||
const { container } = render(Pen, {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
absoluteStrokeWidth: '',
|
||||
},
|
||||
});
|
||||
|
||||
const icon = container.firstElementChild;
|
||||
|
||||
expect(icon).toHaveAttribute('width', '48');
|
||||
expect(icon).toHaveAttribute('stroke', 'red');
|
||||
expect(icon).toHaveAttribute('stroke-width', '1');
|
||||
});
|
||||
|
||||
it('should not scale the strokeWidth when absoluteStrokeWidth is written in kebabCase', () => {
|
||||
const { container } = render(Pen, {
|
||||
props: {
|
||||
size: 48,
|
||||
color: 'red',
|
||||
'stroke-width': '2',
|
||||
'absolute-stroke-width': '',
|
||||
},
|
||||
});
|
||||
|
||||
const icon = container.firstElementChild;
|
||||
|
||||
expect(icon).toHaveAttribute('width', '48');
|
||||
expect(icon).toHaveAttribute('stroke', 'red');
|
||||
expect(icon).toHaveAttribute('stroke-width', '1');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
import { afterEach } from 'vitest';
|
||||
import { cleanup } from '@testing-library/vue';
|
||||
import '@testing-library/jest-dom/vitest';
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
import { IconNode } from '../src/types';
|
||||
|
||||
export const airVent: IconNode = [
|
||||
[
|
||||
'path',
|
||||
{
|
||||
d: 'M6 12H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2',
|
||||
key: 'larmp2',
|
||||
},
|
||||
],
|
||||
['path', { d: 'M6 8h12', key: '6g4wlu' }],
|
||||
['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', key: '1bo8pg' }],
|
||||
['path', { d: 'M6.6 15.6A2 2 0 1 0 10 17v-5', key: 't9h90c' }],
|
||||
];
|
||||
|
||||
export const coffee: IconNode = [
|
||||
['path', { d: 'M17 8h1a4 4 0 1 1 0 8h-1', key: 'jx4kbh' }],
|
||||
['path', { d: 'M3 8h14v9a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4Z', key: '1bxrl0' }],
|
||||
['line', { x1: '6', x2: '6', y1: '2', y2: '4', key: '1cr9l3' }],
|
||||
['line', { x1: '10', x2: '10', y1: '2', y2: '4', key: '170wym' }],
|
||||
['line', { x1: '14', x2: '14', y1: '2', y2: '4', key: '1c5f70' }],
|
||||
];
|
||||
@@ -9,9 +9,10 @@
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"esModuleInterop": true,
|
||||
"allowImportingTsExtensions": true,
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"skipLibCheck": true,
|
||||
"noEmit": true,
|
||||
"types": ["@testing-library/jest-dom"],
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
setupFiles: './tests/setupVitest.js',
|
||||
},
|
||||
});
|
||||
Generated
+259
-1193
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user