Compare commits
10 Commits
next
...
package/an
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae1ca07e36 | ||
|
|
818d99f41e | ||
|
|
a3e7e75b90 | ||
|
|
3edcd9e0c3 | ||
|
|
e851a03672 | ||
|
|
0abfa2f0d5 | ||
|
|
0b8f99326c | ||
|
|
6c1e34df19 | ||
|
|
669f62bb64 | ||
|
|
708d5114d6 |
@@ -9,3 +9,9 @@ strikethrough
|
|||||||
touchpad
|
touchpad
|
||||||
ungroup
|
ungroup
|
||||||
toc
|
toc
|
||||||
|
|
||||||
|
# Brands
|
||||||
|
codepen
|
||||||
|
codesandbox
|
||||||
|
dribbble
|
||||||
|
x.com
|
||||||
|
|||||||
43
.github/workflows/lucide-vue.yml
vendored
@@ -1,43 +0,0 @@
|
|||||||
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
|
|
||||||
1
.github/workflows/release.yml
vendored
@@ -60,7 +60,6 @@ jobs:
|
|||||||
'lucide-svelte',
|
'lucide-svelte',
|
||||||
'@lucide/astro',
|
'@lucide/astro',
|
||||||
'@lucide/svelte',
|
'@lucide/svelte',
|
||||||
'@lucide/vue',
|
|
||||||
]
|
]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
|
|||||||
5
categories/brands.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../category.schema.json",
|
||||||
|
"title": "Brands",
|
||||||
|
"icon": "facebook"
|
||||||
|
}
|
||||||
@@ -15,6 +15,10 @@
|
|||||||
"name": "arrows",
|
"name": "arrows",
|
||||||
"title": "Arrows"
|
"title": "Arrows"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "brands",
|
||||||
|
"title": "Brands"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "buildings",
|
"name": "buildings",
|
||||||
"title": "Buildings"
|
"title": "Buildings"
|
||||||
|
|||||||
@@ -31,12 +31,20 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"@lucide/vue": {
|
"lucide-vue-next": {
|
||||||
"order": 2,
|
"order": 2,
|
||||||
"icon": "vue",
|
"icon": "vue-next",
|
||||||
"docsAlias": "lucide-vue",
|
|
||||||
"packageDirname": "vue",
|
|
||||||
"shields": [
|
"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": {
|
"lucide-svelte": {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export default App;
|
|||||||
language: 'vue',
|
language: 'vue',
|
||||||
title: 'Vue',
|
title: 'Vue',
|
||||||
code: `<script setup>
|
code: `<script setup>
|
||||||
import { $PascalCase } from '@lucide/vue';
|
import { $PascalCase } from 'lucide-vue-next';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ const sidebar: UserConfig<DefaultTheme.Config>['themeConfig']['sidebar'] = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'Lucide Vue',
|
text: 'Lucide Vue',
|
||||||
link: '/guide/packages/lucide-vue',
|
link: '/guide/packages/lucide-vue-next',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: 'Lucide Svelte',
|
text: 'Lucide Svelte',
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ const value = computed({
|
|||||||
color: var(--vp-c-text-2);
|
color: var(--vp-c-text-2);
|
||||||
padding: 3px 8px 3px 3px;
|
padding: 3px 8px 3px 3px;
|
||||||
height: auto;
|
height: auto;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
cursor: text;
|
cursor: text;
|
||||||
@@ -90,7 +90,7 @@ const value = computed({
|
|||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: var(--vp-c-text-1);
|
color: var(--vp-c-text-1);
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
cursor: text;
|
cursor: text;
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ export default {
|
|||||||
label: 'Lucide documentation for React',
|
label: 'Lucide documentation for React',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'lucide-vue',
|
name: 'lucide-vue-next',
|
||||||
logo: '/framework-logos/vue.svg',
|
logo: '/framework-logos/vue.svg',
|
||||||
label: 'Lucide documentation for Vue',
|
label: 'Lucide documentation for Vue 3',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'lucide-svelte',
|
name: 'lucide-svelte',
|
||||||
|
|||||||
@@ -29,12 +29,7 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const iconComponent = computed(() => {
|
const iconComponent = computed(() => {
|
||||||
if (!props.name || !props.iconNode) return null;
|
if (!props.name || !props.iconNode) return null;
|
||||||
try {
|
return createLucideIcon(props.name, props.iconNode);
|
||||||
return createLucideIcon(props.name, props.iconNode);
|
|
||||||
} catch (error) {
|
|
||||||
console.warn(`Icon ${props.name} not found, using fallback`);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const CalendarIcon = createLucideIcon('calendar', Calendar.iconNode);
|
const CalendarIcon = createLucideIcon('calendar', Calendar.iconNode);
|
||||||
@@ -66,7 +61,7 @@ const prettyName = props.name
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="showcase" v-if="iconComponent">
|
<section class="showcase">
|
||||||
<h2 class="title">See this icon in action</h2>
|
<h2 class="title">See this icon in action</h2>
|
||||||
<div class="showcase-grid">
|
<div class="showcase-grid">
|
||||||
<div class="showcase-item column">
|
<div class="showcase-item column">
|
||||||
|
|||||||
@@ -64,24 +64,25 @@ Implementation of the lucide icon library for Vue applications.
|
|||||||
::: code-group
|
::: code-group
|
||||||
|
|
||||||
```sh [pnpm]
|
```sh [pnpm]
|
||||||
pnpm add @lucide/vue
|
pnpm add lucide-vue-next
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [yarn]
|
```sh [yarn]
|
||||||
yarn add @lucide/vue
|
yarn add lucide-vue-next
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [npm]
|
```sh [npm]
|
||||||
npm install @lucide/vue
|
npm install lucide-vue-next
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [bun]
|
```sh [bun]
|
||||||
bun add @lucide/vue
|
bun add lucide-vue-next
|
||||||
```
|
```
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
For more details, see the [documentation](packages/lucide-vue.md).
|
For more details, see the [documentation](packages/lucide-vue-next.md).
|
||||||
|
For Vue 2 use the `lucide-vue` package.
|
||||||
|
|
||||||
## Svelte
|
## Svelte
|
||||||
|
|
||||||
@@ -90,22 +91,22 @@ Implementation of the lucide icon library for Svelte applications.
|
|||||||
::: code-group
|
::: code-group
|
||||||
|
|
||||||
```sh [pnpm]
|
```sh [pnpm]
|
||||||
pnpm add @lucide/svelte
|
pnpm add lucide-svelte
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [yarn]
|
```sh [yarn]
|
||||||
yarn add @lucide/svelte
|
yarn add lucide-svelte
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [npm]
|
```sh [npm]
|
||||||
npm install @lucide/svelte
|
npm install lucide-svelte
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [bun]
|
```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).
|
For more details, see the [documentation](packages/lucide-svelte.md).
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,14 @@ 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.
|
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 one of the framework-specific [packages](../../packages).
|
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)
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|||||||
148
docs/guide/packages/lucide-vue-next.md
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
# Lucide Vue Next
|
||||||
|
|
||||||
|
Vue 3 components for Lucide icons that leverage the Composition API and modern Vue features. Each icon is a reactive Vue component that renders as an inline SVG, providing excellent performance and developer experience in Vue 3 applications.
|
||||||
|
|
||||||
|
**What you can accomplish:**
|
||||||
|
- Use icons as Vue 3 components with full reactivity and TypeScript support
|
||||||
|
- Bind icon properties to reactive data and computed values
|
||||||
|
- Customize icons with props, slots, and Vue's powerful templating system
|
||||||
|
- Integrate seamlessly with Vue 3's Composition API and script setup syntax
|
||||||
|
- Build dynamic interfaces where icons respond to application state changes
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
|
||||||
|
```sh [pnpm]
|
||||||
|
pnpm add 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>
|
||||||
|
```
|
||||||
@@ -9,24 +9,28 @@ Vue 2 components for Lucide icons that integrate with Vue's Options API and temp
|
|||||||
- Build applications using Vue 2's familiar syntax and patterns
|
- Build applications using Vue 2's familiar syntax and patterns
|
||||||
- Bridge the gap while planning migration to Vue 3
|
- Bridge the gap while planning migration to Vue 3
|
||||||
|
|
||||||
|
::: danger
|
||||||
|
This package is deprecated. Vue 2 is EOF See [Announcement](https://v2.vuejs.org/eol/). Migrate to Vue 3.
|
||||||
|
:::
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
::: code-group
|
::: code-group
|
||||||
|
|
||||||
```sh [pnpm]
|
```sh [pnpm]
|
||||||
pnpm add @lucide/vue
|
pnpm add lucide-vue
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [yarn]
|
```sh [yarn]
|
||||||
yarn add @lucide/vue
|
yarn add lucide-vue
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [npm]
|
```sh [npm]
|
||||||
npm install @lucide/vue
|
npm install lucide-vue
|
||||||
```
|
```
|
||||||
|
|
||||||
```sh [bun]
|
```sh [bun]
|
||||||
bun add @lucide/vue
|
bun add lucide-vue
|
||||||
```
|
```
|
||||||
|
|
||||||
:::
|
:::
|
||||||
@@ -39,19 +43,21 @@ Each icon can be imported as a Vue component, which renders an inline SVG Elemen
|
|||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
You can pass additional props to adjust the icon.
|
Additional props can be passed to adjust the icon:
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<script setup>
|
|
||||||
import { Camera } from '@lucide/vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Camera
|
<Camera color="red" :size="32" />
|
||||||
color="red"
|
|
||||||
:size="32"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Camera } from 'lucide-vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'My Component',
|
||||||
|
components: { Camera }
|
||||||
|
};
|
||||||
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Props
|
## Props
|
||||||
@@ -74,28 +80,6 @@ To customize the appearance of an icon, you can pass custom properties as props
|
|||||||
</template>
|
</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
|
## One generic icon component
|
||||||
|
|
||||||
It is possible to create one generic icon component to load icons, but it is not recommended.
|
It is possible to create one generic icon component to load icons, but it is not recommended.
|
||||||
@@ -107,37 +91,30 @@ The example below imports all ES Modules, so exercise caution when using it. Imp
|
|||||||
### Icon Component Example
|
### Icon Component Example
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<script setup>
|
|
||||||
import { computed } from 'vue';
|
|
||||||
import * as icons from "@lucide/vue";
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
size: Number,
|
|
||||||
color: String,
|
|
||||||
strokeWidth: Number,
|
|
||||||
defaultClass: String
|
|
||||||
})
|
|
||||||
|
|
||||||
const icon = computed(() => icons[props.name]);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<component
|
<component :is="icon" />
|
||||||
:is="icon"
|
|
||||||
:size="size"
|
|
||||||
:color="color"
|
|
||||||
:stroke-width="strokeWidth" :default-class="defaultClass"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as icons from 'lucide-vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
icon() {
|
||||||
|
return icons[this.name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using the Icon Component
|
#### Using the Icon Component
|
||||||
|
|
||||||
All other props listed above also work on the `Icon` Component.
|
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -34,11 +34,6 @@
|
|||||||
],
|
],
|
||||||
"destination": "/icons",
|
"destination": "/icons",
|
||||||
"permanent": false
|
"permanent": false
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "/guide/packages/lucide-vue-next",
|
|
||||||
"destination": "/guide/packages/lucide-vue",
|
|
||||||
"permanent": false
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"headers": [
|
"headers": [
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
"account",
|
"account",
|
||||||
"animals",
|
"animals",
|
||||||
"arrows",
|
"arrows",
|
||||||
|
"brands",
|
||||||
"buildings",
|
"buildings",
|
||||||
"charts",
|
"charts",
|
||||||
"communication",
|
"communication",
|
||||||
@@ -133,7 +134,7 @@
|
|||||||
"$defs": {
|
"$defs": {
|
||||||
"iconDeprecationReasons": {
|
"iconDeprecationReasons": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["icon.renamed"]
|
"enum": ["icon.brand"]
|
||||||
},
|
},
|
||||||
"aliasDeprecationReasons": {
|
"aliasDeprecationReasons": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
],
|
],
|
||||||
"categories": [
|
"categories": [
|
||||||
"multimedia",
|
"multimedia",
|
||||||
"connectivity"
|
"connectivity",
|
||||||
|
"devices",
|
||||||
|
"brands"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
"payment"
|
"payment"
|
||||||
],
|
],
|
||||||
"categories": [
|
"categories": [
|
||||||
|
"brands",
|
||||||
"development",
|
"development",
|
||||||
"finance"
|
"finance"
|
||||||
]
|
]
|
||||||
|
|||||||
25
icons/chromium.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"ericfennis"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"browser",
|
||||||
|
"logo"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands"
|
||||||
|
],
|
||||||
|
"aliases": [
|
||||||
|
{
|
||||||
|
"name": "chrome",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "alias.name",
|
||||||
|
"toBeRemovedInVersion": "v1.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
17
icons/chromium.svg
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<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="M10.88 21.94 15.46 14" />
|
||||||
|
<path d="M21.17 8H12" />
|
||||||
|
<path d="M3.95 6.06 8.54 14" />
|
||||||
|
<circle cx="12" cy="12" r="10" />
|
||||||
|
<circle cx="12" cy="12" r="4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 377 B |
17
icons/codepen.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"ericfennis"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands",
|
||||||
|
"development"
|
||||||
|
]
|
||||||
|
}
|
||||||
17
icons/codepen.svg
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<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"
|
||||||
|
>
|
||||||
|
<polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2" />
|
||||||
|
<line x1="12" x2="12" y1="22" y2="15.5" />
|
||||||
|
<polyline points="22 8.5 12 15.5 2 8.5" />
|
||||||
|
<polyline points="2 15.5 12 8.5 22 15.5" />
|
||||||
|
<line x1="12" x2="12" y1="2" y2="8.5" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 454 B |
18
icons/codesandbox.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"csandman",
|
||||||
|
"ericfennis"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands",
|
||||||
|
"development"
|
||||||
|
]
|
||||||
|
}
|
||||||
18
icons/codesandbox.svg
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<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="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
|
||||||
|
<polyline points="7.5 4.21 12 6.81 16.5 4.21" />
|
||||||
|
<polyline points="7.5 19.79 7.5 14.6 3 12" />
|
||||||
|
<polyline points="21 12 16.5 14.6 16.5 19.79" />
|
||||||
|
<polyline points="3.27 6.96 12 12.01 20.73 6.96" />
|
||||||
|
<line x1="12" x2="12" y1="22.08" y2="12" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 595 B |
18
icons/dribbble.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"ahtohbi4"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"design",
|
||||||
|
"social"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands",
|
||||||
|
"social",
|
||||||
|
"design"
|
||||||
|
]
|
||||||
|
}
|
||||||
16
icons/dribbble.svg
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<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"
|
||||||
|
>
|
||||||
|
<circle cx="12" cy="12" r="10" />
|
||||||
|
<path d="M19.13 5.09C15.22 9.14 10 10.44 2.25 10.94" />
|
||||||
|
<path d="M21.75 12.84c-6.62-1.41-12.14 1-16.38 6.32" />
|
||||||
|
<path d="M8.56 2.75c4.37 6 6 9.42 8 17.72" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 408 B |
19
icons/facebook.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"csandman",
|
||||||
|
"ericfennis"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"social"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"social",
|
||||||
|
"brands"
|
||||||
|
]
|
||||||
|
}
|
||||||
13
icons/facebook.svg
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<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="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 289 B |
21
icons/figma.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"csandman",
|
||||||
|
"mittalyashu",
|
||||||
|
"ericfennis"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"design",
|
||||||
|
"tool"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands",
|
||||||
|
"design"
|
||||||
|
]
|
||||||
|
}
|
||||||
17
icons/figma.svg
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<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="M5 5.5A3.5 3.5 0 0 1 8.5 2H12v7H8.5A3.5 3.5 0 0 1 5 5.5z" />
|
||||||
|
<path d="M12 2h3.5a3.5 3.5 0 1 1 0 7H12V2z" />
|
||||||
|
<path d="M12 12.5a3.5 3.5 0 1 1 7 0 3.5 3.5 0 1 1-7 0z" />
|
||||||
|
<path d="M5 19.5A3.5 3.5 0 0 1 8.5 16H12v3.5a3.5 3.5 0 1 1-7 0z" />
|
||||||
|
<path d="M5 12.5A3.5 3.5 0 0 1 8.5 9H12v7H8.5A3.5 3.5 0 0 1 5 12.5z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 534 B |
21
icons/framer.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"csandman",
|
||||||
|
"mittalyashu",
|
||||||
|
"ericfennis"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"design",
|
||||||
|
"tool"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands",
|
||||||
|
"design"
|
||||||
|
]
|
||||||
|
}
|
||||||
13
icons/framer.svg
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<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="M5 16V9h14V2H5l14 14h-7m-7 0 7 7v-7m-7 0h7" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 266 B |
20
icons/github.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"csandman",
|
||||||
|
"ericfennis",
|
||||||
|
"karsa-mistmere"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"version control"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands",
|
||||||
|
"development"
|
||||||
|
]
|
||||||
|
}
|
||||||
14
icons/github.svg
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<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 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" />
|
||||||
|
<path d="M9 18c-4.51 2-5-2-7-2" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 509 B |
20
icons/gitlab.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"csandman",
|
||||||
|
"ericfennis",
|
||||||
|
"karsa-mistmere"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"version control"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands",
|
||||||
|
"development"
|
||||||
|
]
|
||||||
|
}
|
||||||
13
icons/gitlab.svg
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<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="m22 13.29-3.33-10a.42.42 0 0 0-.14-.18.38.38 0 0 0-.22-.11.39.39 0 0 0-.23.07.42.42 0 0 0-.14.18l-2.26 6.67H8.32L6.1 3.26a.42.42 0 0 0-.1-.18.38.38 0 0 0-.26-.08.39.39 0 0 0-.23.07.42.42 0 0 0-.14.18L2 13.29a.74.74 0 0 0 .27.83L12 21l9.69-6.88a.71.71 0 0 0 .31-.83Z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 489 B |
@@ -12,6 +12,7 @@
|
|||||||
],
|
],
|
||||||
"categories": [
|
"categories": [
|
||||||
"shapes",
|
"shapes",
|
||||||
|
"brands",
|
||||||
"development"
|
"development"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
21
icons/instagram.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"csandman",
|
||||||
|
"ericfennis"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"camera",
|
||||||
|
"social"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands",
|
||||||
|
"social",
|
||||||
|
"photography"
|
||||||
|
]
|
||||||
|
}
|
||||||
15
icons/instagram.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"
|
||||||
|
>
|
||||||
|
<rect width="20" height="20" x="2" y="2" rx="5" ry="5" />
|
||||||
|
<path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z" />
|
||||||
|
<line x1="17.5" x2="17.51" y1="6.5" y2="6.5" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 381 B |
20
icons/linkedin.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"okcoker",
|
||||||
|
"csandman",
|
||||||
|
"ericfennis"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"social media",
|
||||||
|
"social"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"social",
|
||||||
|
"brands"
|
||||||
|
]
|
||||||
|
}
|
||||||
15
icons/linkedin.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="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z" />
|
||||||
|
<rect width="4" height="12" x="2" y="9" />
|
||||||
|
<circle cx="4" cy="4" r="2" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 380 B |
@@ -9,8 +9,8 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
>
|
>
|
||||||
<path d="M19 12H2" />
|
<path d="M11 7 6 2" />
|
||||||
|
<path d="M18.992 12H2.041" />
|
||||||
<path d="M21.145 18.38A3.34 3.34 0 0 1 20 16.5a3.3 3.3 0 0 1-1.145 1.88c-.575.46-.855 1.02-.855 1.595A2 2 0 0 0 20 22a2 2 0 0 0 2-2.025c0-.58-.285-1.13-.855-1.595" />
|
<path d="M21.145 18.38A3.34 3.34 0 0 1 20 16.5a3.3 3.3 0 0 1-1.145 1.88c-.575.46-.855 1.02-.855 1.595A2 2 0 0 0 20 22a2 2 0 0 0 2-2.025c0-.58-.285-1.13-.855-1.595" />
|
||||||
<path d="m6 2 5 5" />
|
|
||||||
<path d="m8.5 4.5 2.148-2.148a1.205 1.205 0 0 1 1.704 0l7.296 7.296a1.205 1.205 0 0 1 0 1.704l-7.592 7.592a3.615 3.615 0 0 1-5.112 0l-3.888-3.888a3.615 3.615 0 0 1 0-5.112L5.67 7.33" />
|
<path d="m8.5 4.5 2.148-2.148a1.205 1.205 0 0 1 1.704 0l7.296 7.296a1.205 1.205 0 0 1 0 1.704l-7.592 7.592a3.615 3.615 0 0 1-5.112 0l-3.888-3.888a3.615 3.615 0 0 1 0-5.112L5.67 7.33" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 613 B After Width: | Height: | Size: 622 B |
18
icons/pocket.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"csandman",
|
||||||
|
"ericfennis"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"save"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands"
|
||||||
|
]
|
||||||
|
}
|
||||||
14
icons/pocket.svg
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<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 3a2 2 0 0 1 2 2v6a1 1 0 0 1-20 0V5a2 2 0 0 1 2-2z" />
|
||||||
|
<path d="m8 10 4 4 4-4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 306 B |
19
icons/rail-symbol.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"contributors": [
|
||||||
|
"danielbayley"
|
||||||
|
],
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"tags": [
|
||||||
|
"railway",
|
||||||
|
"train",
|
||||||
|
"track",
|
||||||
|
"line"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"transportation",
|
||||||
|
"navigation"
|
||||||
|
]
|
||||||
|
}
|
||||||
15
icons/rail-symbol.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="M5 15h14" />
|
||||||
|
<path d="M5 9h14" />
|
||||||
|
<path d="m14 20-5-5 6-6-5-5" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 289 B |
22
icons/slack.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"ashygee",
|
||||||
|
"wojtekmaj",
|
||||||
|
"mittalyashu",
|
||||||
|
"ericfennis"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"account",
|
||||||
|
"social",
|
||||||
|
"brands",
|
||||||
|
"development"
|
||||||
|
]
|
||||||
|
}
|
||||||
20
icons/slack.svg
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<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"
|
||||||
|
>
|
||||||
|
<rect width="3" height="8" x="13" y="2" rx="1.5" />
|
||||||
|
<path d="M19 8.5V10h1.5A1.5 1.5 0 1 0 19 8.5" />
|
||||||
|
<rect width="3" height="8" x="8" y="14" rx="1.5" />
|
||||||
|
<path d="M5 15.5V14H3.5A1.5 1.5 0 1 0 5 15.5" />
|
||||||
|
<rect width="8" height="3" x="14" y="13" rx="1.5" />
|
||||||
|
<path d="M15.5 19H14v1.5a1.5 1.5 0 1 0 1.5-1.5" />
|
||||||
|
<rect width="8" height="3" x="2" y="8" rx="1.5" />
|
||||||
|
<path d="M8.5 5H10V3.5A1.5 1.5 0 1 0 8.5 5" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 628 B |
@@ -13,6 +13,7 @@
|
|||||||
"productivity"
|
"productivity"
|
||||||
],
|
],
|
||||||
"categories": [
|
"categories": [
|
||||||
|
"brands",
|
||||||
"gaming"
|
"gaming"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
21
icons/trello.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"bdbch",
|
||||||
|
"csandman",
|
||||||
|
"mittalyashu",
|
||||||
|
"ericfennis"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"brand"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"account",
|
||||||
|
"brands",
|
||||||
|
"development"
|
||||||
|
]
|
||||||
|
}
|
||||||
15
icons/trello.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"
|
||||||
|
>
|
||||||
|
<rect width="18" height="18" x="3" y="3" rx="2" ry="2" />
|
||||||
|
<rect width="3" height="9" x="7" y="7" />
|
||||||
|
<rect width="3" height="5" x="14" y="7" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 357 B |
20
icons/twitch.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"ahtohbi4",
|
||||||
|
"johnletey"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"social"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands",
|
||||||
|
"social",
|
||||||
|
"account",
|
||||||
|
"gaming"
|
||||||
|
]
|
||||||
|
}
|
||||||
13
icons/twitch.svg
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<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="M21 2H3v16h5v4l4-4h5l4-4V2zm-10 9V7m5 4V7" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 265 B |
21
icons/twitter.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"csandman",
|
||||||
|
"ericfennis",
|
||||||
|
"karsa-mistmere"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"social"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"brands",
|
||||||
|
"social",
|
||||||
|
"account"
|
||||||
|
]
|
||||||
|
}
|
||||||
13
icons/twitter.svg
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<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="M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 359 B |
24
icons/youtube.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../icon.schema.json",
|
||||||
|
"deprecated": true,
|
||||||
|
"deprecationReason": "icon.brand",
|
||||||
|
"toBeRemovedInVersion": "v1.0",
|
||||||
|
"contributors": [
|
||||||
|
"colebemis",
|
||||||
|
"csandman",
|
||||||
|
"ericfennis",
|
||||||
|
"karsa-mistmere",
|
||||||
|
"jguddas"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"logo",
|
||||||
|
"social",
|
||||||
|
"video",
|
||||||
|
"play"
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"multimedia",
|
||||||
|
"social",
|
||||||
|
"brands"
|
||||||
|
]
|
||||||
|
}
|
||||||
14
icons/youtube.svg
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<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="M2.5 17a24.12 24.12 0 0 1 0-10 2 2 0 0 1 1.4-1.4 49.56 49.56 0 0 1 16.2 0A2 2 0 0 1 21.5 7a24.12 24.12 0 0 1 0 10 2 2 0 0 1-1.4 1.4 49.55 49.55 0 0 1-16.2 0A2 2 0 0 1 2.5 17" />
|
||||||
|
<path d="m10 15 5-3-5-3z" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 428 B |
73
packages/lucide-angular-next/README.md
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/lucide-icons/lucide">
|
||||||
|
<img src="https://lucide.dev/package-logos/lucide-angular.svg" alt="Lucide icon library for Angular applications." width="540">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
Lucide icon library for Angular applications.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
[](https://www.npmjs.com/package/lucide-angular)
|
||||||
|

|
||||||
|
[](https://lucide.dev/license)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://lucide.dev/guide/">About</a>
|
||||||
|
·
|
||||||
|
<a href="https://lucide.dev/icons/">Icons</a>
|
||||||
|
·
|
||||||
|
<a href="https://lucide.dev/guide/packages/lucide-angular">Documentation</a>
|
||||||
|
·
|
||||||
|
<a href="https://lucide.dev/license">License</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# Lucide Angular
|
||||||
|
|
||||||
|
Implementation of the lucide icon library for angular applications.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pnpm add lucide-angular
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install lucide-angular
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
yarn add lucide-angular
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
bun add lucide-angular
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
For full documentation, visit [lucide.dev](https://lucide.dev/guide/packages/lucide-angular)
|
||||||
|
|
||||||
|
## Community
|
||||||
|
|
||||||
|
Join the [Discord server](https://discord.gg/EH6nSts) to chat with the maintainers and other users.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Lucide is licensed under the ISC license. See [LICENSE](https://lucide.dev/license).
|
||||||
|
|
||||||
|
## Sponsors
|
||||||
|
|
||||||
|
<a href="https://vercel.com?utm_source=lucide&utm_campaign=oss">
|
||||||
|
<img src="https://lucide.dev/vercel.svg" alt="Powered by Vercel" width="200" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://www.digitalocean.com/?refcode=b0877a2caebd&utm_campaign=Referral_Invite&utm_medium=Referral_Program&utm_source=badge"><img src="https://lucide.dev/digitalocean.svg" width="200" alt="DigitalOcean Referral Badge" /></a>
|
||||||
|
|
||||||
|
### Awesome backers 🍺
|
||||||
|
|
||||||
|
<a href="https://www.scipress.io?utm_source=lucide"><img src="https://lucide.dev/sponsors/scipress.svg" width="180" alt="Scipress sponsor badge" /></a>
|
||||||
|
<a href="https://github.com/pdfme/pdfme"><img src="https://lucide.dev/sponsors/pdfme.svg" width="180" alt="pdfme sponsor badge" /></a>
|
||||||
45
packages/lucide-angular-next/angular.json
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"version": 1,
|
||||||
|
"cli": {
|
||||||
|
"packageManager": "npm"
|
||||||
|
},
|
||||||
|
"newProjectRoot": "projects",
|
||||||
|
"projects": {
|
||||||
|
"@lucide/angular": {
|
||||||
|
"projectType": "library",
|
||||||
|
"root": ".",
|
||||||
|
"sourceRoot": "./src",
|
||||||
|
"prefix": "lib",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular/build:ng-packagr",
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"tsConfig": "./tsconfig.lib.prod.json"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"tsConfig": "./tsconfig.lib.json"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "production"
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular/build:unit-test",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": "./tsconfig.spec.json",
|
||||||
|
"coverage": true,
|
||||||
|
"coverageReporters": ["html", "lcov"],
|
||||||
|
"coverageExclude": ["src/icons/*"],
|
||||||
|
"coverageThresholds": {
|
||||||
|
"statements": 80,
|
||||||
|
"branches": 80,
|
||||||
|
"functions": 80,
|
||||||
|
"lines": 80
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
packages/lucide-angular-next/ng-package.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./node_modules/ng-packagr/ng-package.schema.json",
|
||||||
|
"dest": "./dist",
|
||||||
|
"lib": {
|
||||||
|
"entryFile": "./src/public-api.ts"
|
||||||
|
}
|
||||||
|
}
|
||||||
56
packages/lucide-angular-next/package.json
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"name": "@lucide/angular",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"watch": "ng build --watch --configuration development",
|
||||||
|
"prebuild": "pnpm clean && pnpm copy:license && pnpm build:icons",
|
||||||
|
"build": "pnpm build:ng",
|
||||||
|
"copy:license": "cp ../../LICENSE ./LICENSE",
|
||||||
|
"clean": "rm -rf dist && rm -rf ./src/icons/*.ts",
|
||||||
|
"build:icons": "build-icons --output=./src --templateSrc=./scripts/exportTemplate.mts --renderUniqueKey --iconFileExtension=.ts --exportFileName=lucide-angular.ts",
|
||||||
|
"build:ng": "ng build --configuration production",
|
||||||
|
"test": "ng test --no-watch",
|
||||||
|
"test:watch": "ng test",
|
||||||
|
"lint": "npx eslint 'src/**/*.{js,jsx,ts,tsx,html,css,scss}' --quiet --fix",
|
||||||
|
"e2e": "ng e2e",
|
||||||
|
"version": "pnpm version --git-tag-version=false"
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"printWidth": 100,
|
||||||
|
"singleQuote": true,
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "*.html",
|
||||||
|
"options": {
|
||||||
|
"parser": "angular"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"devDependencies": {
|
||||||
|
"@angular/build": "^21.0.3",
|
||||||
|
"@angular/cli": "^21.0.3",
|
||||||
|
"@angular/common": "^21.0.0",
|
||||||
|
"@angular/compiler": "^21.0.0",
|
||||||
|
"@angular/compiler-cli": "^21.0.0",
|
||||||
|
"@angular/core": "^21.0.0",
|
||||||
|
"@angular/forms": "^21.0.0",
|
||||||
|
"@angular/platform-browser": "^21.0.0",
|
||||||
|
"@angular/router": "^21.0.0",
|
||||||
|
"@lucide/build-icons": "workspace:*",
|
||||||
|
"@vitest/browser-playwright": "^4.0.16",
|
||||||
|
"@vitest/coverage-v8": "^4.0.16",
|
||||||
|
"jsdom": "^27.1.0",
|
||||||
|
"ng-packagr": "^21.0.0",
|
||||||
|
"rxjs": "~7.8.0",
|
||||||
|
"tslib": "^2.3.0",
|
||||||
|
"typescript": "~5.9.2",
|
||||||
|
"vitest": "^4.0.16"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": "13.x - 21.x",
|
||||||
|
"@angular/core": "13.x - 21.x"
|
||||||
|
}
|
||||||
|
}
|
||||||
68
packages/lucide-angular-next/scripts/exportTemplate.mts
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import base64SVG from '@lucide/build-icons/utils/base64SVG';
|
||||||
|
import defineExportTemplate from '@lucide/build-icons/utils/defineExportTemplate';
|
||||||
|
|
||||||
|
export default defineExportTemplate(async ({
|
||||||
|
componentName,
|
||||||
|
iconName,
|
||||||
|
children,
|
||||||
|
getSvg,
|
||||||
|
deprecated,
|
||||||
|
deprecationReason,
|
||||||
|
aliases = [],
|
||||||
|
toPascalCase,
|
||||||
|
}) => {
|
||||||
|
const svgContents = await getSvg();
|
||||||
|
const svgBase64 = base64SVG(svgContents);
|
||||||
|
const angularComponentName = `Lucide${componentName}`;
|
||||||
|
const selectors = [`svg[lucide${toPascalCase(iconName)}]`];
|
||||||
|
const aliasComponentNames: string[] = [];
|
||||||
|
for (const alias of aliases) {
|
||||||
|
const aliasName = typeof alias === 'string' ? alias : alias.name;
|
||||||
|
const aliasComponentName = `Lucide${toPascalCase(aliasName)}`;
|
||||||
|
const aliasSelector = `svg[lucide${toPascalCase(aliasName)}]`;
|
||||||
|
if (!selectors.includes(aliasSelector)) {
|
||||||
|
selectors.push(aliasSelector);
|
||||||
|
}
|
||||||
|
if (aliasComponentName !== angularComponentName && !aliasComponentNames.includes(aliasComponentName)) {
|
||||||
|
aliasComponentNames.push(aliasComponentName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `\
|
||||||
|
import { LucideIconData } from '../types';
|
||||||
|
import { LucideIconBase } from '../lucide-icon-base';
|
||||||
|
import { Component, signal } from '@angular/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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-angular - Documentation
|
||||||
|
*
|
||||||
|
* @param {Object} props - Lucide icons props and any valid SVG attribute
|
||||||
|
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: '${selectors.join(', ')}',
|
||||||
|
templateUrl: '../lucide-icon.html',
|
||||||
|
standalone: true,
|
||||||
|
})
|
||||||
|
export class ${angularComponentName} extends LucideIconBase {
|
||||||
|
static iconData: LucideIconData = ${JSON.stringify(children)};
|
||||||
|
static iconName = '${iconName}';
|
||||||
|
override readonly icon = signal(${angularComponentName}.iconData);
|
||||||
|
override readonly name = signal(${angularComponentName}.iconName);
|
||||||
|
}
|
||||||
|
|
||||||
|
${aliasComponentNames.map((aliasComponentName) => {
|
||||||
|
return `
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
* @see ${angularComponentName}
|
||||||
|
*/
|
||||||
|
export const ${aliasComponentName} = ${angularComponentName};
|
||||||
|
`;
|
||||||
|
}).join(`\n\n`)}
|
||||||
|
`;
|
||||||
|
});
|
||||||
11
packages/lucide-angular-next/src/default-attributes.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export default {
|
||||||
|
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',
|
||||||
|
};
|
||||||
25
packages/lucide-angular-next/src/lucide-config.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { LUCIDE_CONFIG, lucideDefaultConfig, provideLucideConfig } from './lucide-config';
|
||||||
|
|
||||||
|
describe('Lucide config', () => {
|
||||||
|
describe('LUCIDE_CONFIG', () => {
|
||||||
|
it('should use default', () => {
|
||||||
|
expect(TestBed.inject(LUCIDE_CONFIG)).toBe(lucideDefaultConfig);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('provideLucideConfig', () => {
|
||||||
|
it('should use defaults', () => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [
|
||||||
|
provideLucideConfig({
|
||||||
|
size: 18,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
expect(TestBed.inject(LUCIDE_CONFIG)).toEqual({
|
||||||
|
...lucideDefaultConfig,
|
||||||
|
size: 18,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
38
packages/lucide-angular-next/src/lucide-config.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { InjectionToken, Provider } from '@angular/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A configuration service for Lucide icon components.
|
||||||
|
*
|
||||||
|
* You can inject this service, typically in AppComponent, and customize its property values in
|
||||||
|
* order to provide default values for all the icons used in the application.
|
||||||
|
*/
|
||||||
|
export interface LucideConfig {
|
||||||
|
color: string;
|
||||||
|
size: number;
|
||||||
|
strokeWidth: number;
|
||||||
|
absoluteStrokeWidth: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const lucideDefaultConfig: LucideConfig = {
|
||||||
|
color: 'currentColor',
|
||||||
|
size: 24,
|
||||||
|
strokeWidth: 2,
|
||||||
|
absoluteStrokeWidth: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LUCIDE_CONFIG = new InjectionToken<LucideConfig>(
|
||||||
|
'Lucide icon config',
|
||||||
|
{
|
||||||
|
factory: () => lucideDefaultConfig,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export function provideLucideConfig(config: Partial<LucideConfig>): Provider {
|
||||||
|
return {
|
||||||
|
provide: LUCIDE_CONFIG,
|
||||||
|
useValue: {
|
||||||
|
...lucideDefaultConfig,
|
||||||
|
...config,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
114
packages/lucide-angular-next/src/lucide-icon-base.ts
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
import {
|
||||||
|
Component,
|
||||||
|
computed,
|
||||||
|
effect,
|
||||||
|
ElementRef,
|
||||||
|
inject,
|
||||||
|
input,
|
||||||
|
Renderer2,
|
||||||
|
Signal,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { LUCIDE_CONFIG } from './lucide-config';
|
||||||
|
import { LucideIconData, Nullable } from './types';
|
||||||
|
import defaultAttributes from './default-attributes';
|
||||||
|
import { formatFixed } from './utils/format-fixed';
|
||||||
|
import { toKebabCase } from './utils/to-kebab-case';
|
||||||
|
|
||||||
|
function transformNumericStringInput(
|
||||||
|
value: Nullable<string | number>,
|
||||||
|
defaultValue: number,
|
||||||
|
): number {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
const parsedValue = parseInt(value, 10);
|
||||||
|
if (isNaN(parsedValue)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return parsedValue;
|
||||||
|
}
|
||||||
|
return value ?? defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
// eslint-disable-next-line @angular-eslint/component-selector
|
||||||
|
selector: 'svg[lucideIcon]',
|
||||||
|
templateUrl: './lucide-icon.html',
|
||||||
|
host: {
|
||||||
|
...defaultAttributes,
|
||||||
|
class: 'lucide',
|
||||||
|
'[attr.width]': 'size().toString(10)',
|
||||||
|
'[attr.height]': 'size().toString(10)',
|
||||||
|
'[attr.stroke]': 'color()',
|
||||||
|
'[attr.stroke-width]': 'computedStrokeWidth()',
|
||||||
|
'[attr.aria-hidden]': 'ariaHidden()',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
export abstract class LucideIconBase {
|
||||||
|
abstract icon: Signal<Nullable<LucideIconData>>;
|
||||||
|
abstract name: Signal<Nullable<string>>;
|
||||||
|
protected readonly iconConfig = inject(LUCIDE_CONFIG);
|
||||||
|
protected readonly elRef = inject(ElementRef);
|
||||||
|
protected readonly renderer = inject(Renderer2);
|
||||||
|
readonly title = input<Nullable<string>>();
|
||||||
|
readonly ariaHidden = computed(() => {
|
||||||
|
return !this.title();
|
||||||
|
});
|
||||||
|
readonly size = input(this.iconConfig.size, {
|
||||||
|
transform: (value: Nullable<string | number>) =>
|
||||||
|
transformNumericStringInput(value, this.iconConfig.size),
|
||||||
|
});
|
||||||
|
readonly color = input(this.iconConfig.color, {
|
||||||
|
transform: (value: Nullable<string>) => value ?? this.iconConfig.color,
|
||||||
|
});
|
||||||
|
readonly strokeWidth = input(this.iconConfig.strokeWidth, {
|
||||||
|
transform: (value: Nullable<string | number>) =>
|
||||||
|
transformNumericStringInput(value, this.iconConfig.strokeWidth),
|
||||||
|
});
|
||||||
|
readonly absoluteStrokeWidth = input(this.iconConfig.absoluteStrokeWidth, {
|
||||||
|
transform: (value: Nullable<boolean>) => value ?? this.iconConfig.absoluteStrokeWidth,
|
||||||
|
});
|
||||||
|
protected readonly computedStrokeWidth = computed(() => {
|
||||||
|
const strokeWidth = this.strokeWidth();
|
||||||
|
const size = this.size();
|
||||||
|
return this.absoluteStrokeWidth()
|
||||||
|
? formatFixed(strokeWidth / (size / 24))
|
||||||
|
: strokeWidth.toString(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
effect((onCleanup) => {
|
||||||
|
const icon = this.icon();
|
||||||
|
if (icon) {
|
||||||
|
const elements = icon.map(([name, attrs]) => {
|
||||||
|
const element = this.renderer.createElement(name, 'http://www.w3.org/2000/svg');
|
||||||
|
for (const [name, value] of Object.entries(attrs)) {
|
||||||
|
this.renderer.setAttribute(
|
||||||
|
element,
|
||||||
|
name,
|
||||||
|
typeof value === 'number' ? value.toString(10) : value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.renderer.appendChild(this.elRef.nativeElement, element);
|
||||||
|
return element;
|
||||||
|
});
|
||||||
|
onCleanup(() => {
|
||||||
|
for (const element of elements) {
|
||||||
|
this.renderer.removeChild(this.elRef.nativeElement, element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
effect((onCleanup) => {
|
||||||
|
const name = this.name();
|
||||||
|
if (name) {
|
||||||
|
const cssClass = `lucide-${toKebabCase(name)}`;
|
||||||
|
this.renderer.addClass(this.elRef.nativeElement, cssClass);
|
||||||
|
onCleanup(() => {
|
||||||
|
this.renderer.removeClass(this.elRef.nativeElement, cssClass);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
4
packages/lucide-angular-next/src/lucide-icon.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
@if (title(); as titleValue) {
|
||||||
|
<title>{{ titleValue }}</title>
|
||||||
|
}
|
||||||
|
<ng-content />
|
||||||
243
packages/lucide-angular-next/src/lucide-icon.spec.ts
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
import { Component, input, inputBinding, signal, WritableSignal } from '@angular/core';
|
||||||
|
import { LucideIcon } from './lucide-icon';
|
||||||
|
import { LucideIconData, LucideIconInput } from './types';
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { provideLucideIcons } from './lucide-icons';
|
||||||
|
import { LucideActivity } from './icons/activity';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
template: `@if (icon(); as iconData) {
|
||||||
|
<svg [lucideIcon]="iconData">
|
||||||
|
<rect x="1" y="1" width="22" height="22" />
|
||||||
|
</svg>
|
||||||
|
}`,
|
||||||
|
imports: [LucideIcon],
|
||||||
|
})
|
||||||
|
class TestHostComponent {
|
||||||
|
readonly icon = input<LucideIconData>();
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('LucideIcon', () => {
|
||||||
|
let component: LucideIcon;
|
||||||
|
let fixture: ComponentFixture<LucideIcon>;
|
||||||
|
let icon: WritableSignal<LucideIconInput | null | undefined>;
|
||||||
|
let name: WritableSignal<string | undefined>;
|
||||||
|
let title: WritableSignal<string | undefined>;
|
||||||
|
let color: WritableSignal<string | undefined>;
|
||||||
|
let size: WritableSignal<string | number | undefined>;
|
||||||
|
let strokeWidth: WritableSignal<string | number | undefined>;
|
||||||
|
let absoluteStrokeWidth: WritableSignal<boolean | undefined>;
|
||||||
|
const getSvgAttribute = (attr: string) => fixture.nativeElement.getAttribute(attr);
|
||||||
|
const testIcon: LucideIconData = [['polyline', { points: '1 1 22 22' }]];
|
||||||
|
const testIcon2: LucideIconData = [
|
||||||
|
['circle', { cx: 12, cy: 12, r: 8 }],
|
||||||
|
['polyline', { points: '1 1 22 22' }],
|
||||||
|
];
|
||||||
|
beforeEach(async () => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [provideLucideIcons({ demo: testIcon })],
|
||||||
|
});
|
||||||
|
icon = signal('demo');
|
||||||
|
name = signal(undefined);
|
||||||
|
title = signal(undefined);
|
||||||
|
color = signal(undefined);
|
||||||
|
size = signal(undefined);
|
||||||
|
strokeWidth = signal(undefined);
|
||||||
|
absoluteStrokeWidth = signal(undefined);
|
||||||
|
fixture = TestBed.createComponent(LucideIcon, {
|
||||||
|
inferTagName: true,
|
||||||
|
bindings: [
|
||||||
|
inputBinding('lucideIcon', icon),
|
||||||
|
inputBinding('name', name),
|
||||||
|
inputBinding('title', title),
|
||||||
|
inputBinding('color', color),
|
||||||
|
inputBinding('size', size),
|
||||||
|
inputBinding('strokeWidth', strokeWidth),
|
||||||
|
inputBinding('absoluteStrokeWidth', absoluteStrokeWidth),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render children', () => {
|
||||||
|
icon.set(testIcon2);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.nativeElement.innerHTML).toBe(
|
||||||
|
'<!--container--><circle cx="12" cy="12" r="8"></circle><polyline points="1 1 22 22"></polyline>',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove children on change', () => {
|
||||||
|
icon.set(null);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(fixture.nativeElement.innerHTML).toBe('<!--container-->');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('iconInput', () => {
|
||||||
|
it('should support LucideIconData input', () => {
|
||||||
|
icon.set(testIcon);
|
||||||
|
name.set('custom-name');
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(component.icon()).toBe(testIcon);
|
||||||
|
expect(component.name()).toBe('custom-name');
|
||||||
|
expect(fixture.nativeElement.innerHTML).toBe(
|
||||||
|
'<!--container--><polyline points="1 1 22 22"></polyline>',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should support LucideIconComponentType input', () => {
|
||||||
|
icon.set(LucideActivity);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(component.icon()).toBe(LucideActivity.iconData);
|
||||||
|
expect(component.name()).toBe(LucideActivity.iconName);
|
||||||
|
});
|
||||||
|
it('should support string icon name', () => {
|
||||||
|
icon.set('demo');
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(component.icon()).toBe(testIcon);
|
||||||
|
expect(component.name()).toBe('demo');
|
||||||
|
});
|
||||||
|
it('should throw error if no icon founds', () => {
|
||||||
|
icon.set('invalid');
|
||||||
|
expect(() => fixture.detectChanges()).toThrowError(`Unable to resolve icon 'invalid'`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('class', () => {
|
||||||
|
it('should add all classes', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('class')).toBe('lucide lucide-demo');
|
||||||
|
});
|
||||||
|
it('should add class from name, even if icon has name', () => {
|
||||||
|
icon.set(LucideActivity);
|
||||||
|
name.set('custom-name');
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(getSvgAttribute('class')).toBe('lucide lucide-custom-name');
|
||||||
|
});
|
||||||
|
it('should add class icon if available', () => {
|
||||||
|
icon.set(LucideActivity);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(getSvgAttribute('class')).toBe('lucide lucide-activity');
|
||||||
|
});
|
||||||
|
it('should remove class on change', () => {
|
||||||
|
icon.set(null);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('class')).toBe('lucide');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('color', () => {
|
||||||
|
it('should default to currentColor', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('stroke')).toBe('currentColor');
|
||||||
|
});
|
||||||
|
it('should set color', () => {
|
||||||
|
color.set('red');
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('stroke')).toBe('red');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('size', () => {
|
||||||
|
it('should default to 24', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('width')).toBe('24');
|
||||||
|
expect(getSvgAttribute('height')).toBe('24');
|
||||||
|
});
|
||||||
|
it('should set size', () => {
|
||||||
|
size.set(12);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('width')).toBe('12');
|
||||||
|
expect(getSvgAttribute('height')).toBe('12');
|
||||||
|
});
|
||||||
|
it('should allow string size', () => {
|
||||||
|
size.set('18');
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('width')).toBe('18');
|
||||||
|
expect(getSvgAttribute('height')).toBe('18');
|
||||||
|
});
|
||||||
|
it('should use default on invalid string', () => {
|
||||||
|
size.set('large');
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('width')).toBe('24');
|
||||||
|
expect(getSvgAttribute('height')).toBe('24');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('strokeWidth', () => {
|
||||||
|
it('should default to 2', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('stroke-width')).toBe('2');
|
||||||
|
});
|
||||||
|
it('should set stroke width', () => {
|
||||||
|
strokeWidth.set(1.41);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('stroke-width')).toBe('1.41');
|
||||||
|
});
|
||||||
|
it('should allow string stroke width', () => {
|
||||||
|
strokeWidth.set('1px');
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('stroke-width')).toBe('1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('absoluteStrokeWidth', () => {
|
||||||
|
it('should not adjust stroke width', () => {
|
||||||
|
strokeWidth.set(2);
|
||||||
|
size.set(12);
|
||||||
|
absoluteStrokeWidth.set(false);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('stroke-width')).toBe('2');
|
||||||
|
});
|
||||||
|
it('should adjust stroke width', () => {
|
||||||
|
strokeWidth.set(2);
|
||||||
|
size.set(12);
|
||||||
|
absoluteStrokeWidth.set(true);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('stroke-width')).toBe('4');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('title', () => {
|
||||||
|
it('should set title if provided', () => {
|
||||||
|
title.set('Foobar');
|
||||||
|
fixture.detectChanges();
|
||||||
|
const titleEl = fixture.debugElement.query(By.css('title')).nativeElement;
|
||||||
|
expect(titleEl).toBeDefined();
|
||||||
|
expect(titleEl.textContent).toBe('Foobar');
|
||||||
|
});
|
||||||
|
it('should not set aria-hidden when title is set', () => {
|
||||||
|
title.set('Foobar');
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('aria-hidden')).toBeUndefined;
|
||||||
|
});
|
||||||
|
it('should set aria-hidden if no title is provided', () => {
|
||||||
|
title.set(undefined);
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(getSvgAttribute('aria-hidden')).toBeUndefined;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('content projection', () => {
|
||||||
|
it('should project content', () => {
|
||||||
|
const hostFixture = TestBed.createComponent(TestHostComponent);
|
||||||
|
hostFixture.componentRef.setInput('icon', testIcon);
|
||||||
|
hostFixture.detectChanges();
|
||||||
|
hostFixture.componentRef.setInput('icon', testIcon2);
|
||||||
|
hostFixture.detectChanges();
|
||||||
|
const rect = hostFixture.debugElement.query(By.css('rect')).nativeElement;
|
||||||
|
expect(rect).toBeInstanceOf(SVGElement);
|
||||||
|
expect(rect.outerHTML).toBe('<rect x="1" y="1" width="22" height="22"></rect>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
62
packages/lucide-angular-next/src/lucide-icon.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { Component, computed, inject, input } from '@angular/core';
|
||||||
|
import { isLucideIconComponent, isLucideIconData, LucideIconInput } from './types';
|
||||||
|
import { LucideIconBase } from './lucide-icon-base';
|
||||||
|
import { LUCIDE_ICONS } from './lucide-icons';
|
||||||
|
import { LucideIconData } from './types';
|
||||||
|
import { toKebabCase } from './utils/to-kebab-case';
|
||||||
|
|
||||||
|
interface LucideResolvedIcon {
|
||||||
|
name?: string | null;
|
||||||
|
data: LucideIconData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'svg[lucideIcon]',
|
||||||
|
templateUrl: './lucide-icon.html',
|
||||||
|
standalone: true,
|
||||||
|
})
|
||||||
|
export class LucideIcon extends LucideIconBase {
|
||||||
|
protected readonly icons = inject(LUCIDE_ICONS);
|
||||||
|
readonly nameInput = input<string | null>(null, { alias: 'name' });
|
||||||
|
readonly iconInput = input.required<LucideIconInput | null>({
|
||||||
|
alias: 'lucideIcon',
|
||||||
|
});
|
||||||
|
readonly resolvedIcon = computed<LucideResolvedIcon | null>(() => {
|
||||||
|
return this.resolveIcon(this.nameInput(), this.iconInput());
|
||||||
|
});
|
||||||
|
override readonly name = computed<string | null>(() => {
|
||||||
|
return this.resolvedIcon()?.name ?? null;
|
||||||
|
});
|
||||||
|
override readonly icon = computed<LucideIconData | null>(() => {
|
||||||
|
return this.resolvedIcon()?.data ?? null;
|
||||||
|
});
|
||||||
|
|
||||||
|
protected resolveIcon(
|
||||||
|
name: string | null | undefined,
|
||||||
|
icon: LucideIconInput | null | undefined,
|
||||||
|
): LucideResolvedIcon | null {
|
||||||
|
if (isLucideIconData(icon)) {
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
data: icon,
|
||||||
|
};
|
||||||
|
} else if (isLucideIconComponent(icon)) {
|
||||||
|
return {
|
||||||
|
name: name ?? icon.iconName,
|
||||||
|
data: icon.iconData,
|
||||||
|
};
|
||||||
|
} else if (typeof icon === 'string') {
|
||||||
|
const name = toKebabCase(icon);
|
||||||
|
if (name in this.icons) {
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
data: this.icons[name],
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unable to resolve icon '${icon}'`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
44
packages/lucide-angular-next/src/lucide-icons.spec.ts
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { LUCIDE_ICONS, provideLucideIcons } from './lucide-icons';
|
||||||
|
import { LucideIconData } from './types';
|
||||||
|
import { LucideActivity } from './icons/activity';
|
||||||
|
import { LucideCircle } from './icons/circle';
|
||||||
|
import { LucideSquareX } from './icons/square-x';
|
||||||
|
|
||||||
|
describe('Lucide icons', () => {
|
||||||
|
describe('LUCIDE_ICONS', () => {
|
||||||
|
it('should default to empty map', () => {
|
||||||
|
expect(TestBed.inject(LUCIDE_ICONS)).toEqual({});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('provideLucideIcons', () => {
|
||||||
|
const mockIcon: LucideIconData = [['polyline', { points: '1 1 22 22' }]];
|
||||||
|
const mockIcon2: LucideIconData = [['circle', { cx: 12, cy: 12, r: 8 }]];
|
||||||
|
it('should accept dictionary of icons', () => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [
|
||||||
|
provideLucideIcons({
|
||||||
|
DemoIcon: mockIcon,
|
||||||
|
MockIcon: mockIcon2,
|
||||||
|
TestIcon: LucideActivity,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
expect(TestBed.inject(LUCIDE_ICONS)).toEqual({
|
||||||
|
'demo-icon': mockIcon,
|
||||||
|
'mock-icon': mockIcon2,
|
||||||
|
[LucideActivity.iconName]: LucideActivity.iconData,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should accept list of icon components', () => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [provideLucideIcons([LucideActivity, LucideSquareX, LucideCircle])],
|
||||||
|
});
|
||||||
|
expect(TestBed.inject(LUCIDE_ICONS)).toEqual({
|
||||||
|
[LucideActivity.iconName]: LucideActivity.iconData,
|
||||||
|
[LucideSquareX.iconName]: LucideSquareX.iconData,
|
||||||
|
[LucideCircle.iconName]: LucideCircle.iconData,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
34
packages/lucide-angular-next/src/lucide-icons.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { InjectionToken, Provider } from '@angular/core';
|
||||||
|
import { LucideIconData, LucideIcons } from './types';
|
||||||
|
import { isLucideIconComponent, LucideIconComponentType } from './types';
|
||||||
|
import { toKebabCase } from './utils/to-kebab-case';
|
||||||
|
|
||||||
|
export const LUCIDE_ICONS = new InjectionToken<LucideIcons>('Lucide icons', {
|
||||||
|
factory: () => ({}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export function provideLucideIcons(
|
||||||
|
icons: Record<string, LucideIconData | LucideIconComponentType> | Array<LucideIconComponentType>,
|
||||||
|
): Provider {
|
||||||
|
if (Array.isArray(icons)) {
|
||||||
|
return {
|
||||||
|
provide: LUCIDE_ICONS,
|
||||||
|
useValue: icons.reduce((acc, icon) => {
|
||||||
|
acc[toKebabCase(icon.iconName)] = icon.iconData;
|
||||||
|
return acc;
|
||||||
|
}, {} as LucideIcons),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
provide: LUCIDE_ICONS,
|
||||||
|
useValue: Object.entries(icons).reduce((acc, [name, icon]) => {
|
||||||
|
if (isLucideIconComponent(icon)) {
|
||||||
|
acc[icon.iconName] = icon.iconData;
|
||||||
|
} else {
|
||||||
|
acc[toKebabCase(name)] = icon;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {} as LucideIcons),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
7
packages/lucide-angular-next/src/public-api.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import * as icons from './icons/lucide-angular';
|
||||||
|
|
||||||
|
export * from './lucide-config';
|
||||||
|
export * from './lucide-icon';
|
||||||
|
export * from './lucide-icons';
|
||||||
|
export * from './types';
|
||||||
|
export { icons };
|
||||||
34
packages/lucide-angular-next/src/types.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { InputSignal, Signal, Type } from '@angular/core';
|
||||||
|
|
||||||
|
type HtmlAttributes = { [key: string]: string | number };
|
||||||
|
export type LucideIconNode = readonly [string, HtmlAttributes];
|
||||||
|
export type LucideIconData = readonly LucideIconNode[];
|
||||||
|
export type LucideIcons = { [key: string]: LucideIconData };
|
||||||
|
|
||||||
|
export interface LucideIconComponent {
|
||||||
|
name: Signal<Nullable<string>>;
|
||||||
|
icon: Signal<Nullable<LucideIconData>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LucideIconComponentType = Type<LucideIconComponent> & {
|
||||||
|
iconName: string;
|
||||||
|
iconData: LucideIconData;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function isLucideIconData(icon: unknown): icon is LucideIconData {
|
||||||
|
return Array.isArray(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isLucideIconComponent(icon: unknown): icon is LucideIconComponentType {
|
||||||
|
return (
|
||||||
|
icon instanceof Type &&
|
||||||
|
'iconData' in icon &&
|
||||||
|
Array.isArray(icon.iconData) &&
|
||||||
|
'iconName' in icon &&
|
||||||
|
typeof icon.iconName === 'string'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LucideIconInput = LucideIconComponentType | LucideIconData | string;
|
||||||
|
|
||||||
|
export type Nullable<T> = T | null | undefined;
|
||||||
3
packages/lucide-angular-next/src/utils/format-fixed.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function formatFixed(number: number, decimals = 3): string {
|
||||||
|
return parseFloat(number.toFixed(decimals)).toString(10);
|
||||||
|
}
|
||||||
2
packages/lucide-angular-next/src/utils/to-kebab-case.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export const toKebabCase = (name: string) =>
|
||||||
|
name.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
||||||
38
packages/lucide-angular-next/tsconfig.json
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"compileOnSave": false,
|
||||||
|
"compilerOptions": {
|
||||||
|
"paths": {
|
||||||
|
"@lucide/angular": [
|
||||||
|
"./dist"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"noPropertyAccessFromIndexSignature": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"importHelpers": true,
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "preserve"
|
||||||
|
},
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"enableI18nLegacyMessageIdFormat": false,
|
||||||
|
"strictInjectionParameters": true,
|
||||||
|
"strictInputAccessModifiers": true,
|
||||||
|
"strictTemplates": true
|
||||||
|
},
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.lib.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.spec.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
packages/lucide-angular-next/tsconfig.lib.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./out-tsc/lib",
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"inlineSources": true,
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/*.spec.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
11
packages/lucide-angular-next/tsconfig.lib.prod.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.lib.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"declarationMap": false
|
||||||
|
},
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"compilationMode": "partial"
|
||||||
|
}
|
||||||
|
}
|
||||||
15
packages/lucide-angular-next/tsconfig.spec.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||||
|
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"vitest/globals"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.d.ts",
|
||||||
|
"src/**/*.spec.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "lucide-angular",
|
"name": "@lucide/angular",
|
||||||
"description": "A Lucide icon library package for Angular applications.",
|
"description": "A Lucide icon library package for Angular applications",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"author": "SMAH1",
|
"author": "SMAH1",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
@@ -38,19 +38,19 @@
|
|||||||
"version": "pnpm version --git-tag-version=false"
|
"version": "pnpm version --git-tag-version=false"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "~13.3.11",
|
"@angular-devkit/build-angular": "~17.3.14",
|
||||||
"@angular-eslint/builder": "~13.0.0",
|
"@angular-eslint/builder": "~17.5.3",
|
||||||
"@angular-eslint/eslint-plugin": "~13.0.0",
|
"@angular-eslint/eslint-plugin": "~17.5.3",
|
||||||
"@angular-eslint/eslint-plugin-template": "~13.0.0",
|
"@angular-eslint/eslint-plugin-template": "~17.5.3",
|
||||||
"@angular-eslint/schematics": "~13.0.0",
|
"@angular-eslint/schematics": "~17.5.3",
|
||||||
"@angular-eslint/template-parser": "~13.0.0",
|
"@angular-eslint/template-parser": "~17.5.3",
|
||||||
"@angular/cli": "~13.3.11",
|
"@angular/cli": "~17.3.14",
|
||||||
"@angular/common": "~13.3.0",
|
"@angular/common": "~17.3.12",
|
||||||
"@angular/compiler": "~13.3.0",
|
"@angular/compiler": "~17.3.12",
|
||||||
"@angular/compiler-cli": "~13.3.0",
|
"@angular/compiler-cli": "~17.3.12",
|
||||||
"@angular/core": "~13.3.0",
|
"@angular/core": "~17.3.12",
|
||||||
"@angular/platform-browser": "~13.3.0",
|
"@angular/platform-browser": "~17.3.12",
|
||||||
"@angular/platform-browser-dynamic": "~13.3.0",
|
"@angular/platform-browser-dynamic": "~17.3.12",
|
||||||
"@lucide/build-icons": "workspace:*",
|
"@lucide/build-icons": "workspace:*",
|
||||||
"@types/jasmine": "~3.10.0",
|
"@types/jasmine": "~3.10.0",
|
||||||
"@types/node": "^12.11.1",
|
"@types/node": "^12.11.1",
|
||||||
@@ -65,12 +65,12 @@
|
|||||||
"karma-coverage": "~2.1.0",
|
"karma-coverage": "~2.1.0",
|
||||||
"karma-jasmine": "~4.0.0",
|
"karma-jasmine": "~4.0.0",
|
||||||
"karma-jasmine-html-reporter": "~1.7.0",
|
"karma-jasmine-html-reporter": "~1.7.0",
|
||||||
"ng-packagr": "^13.3.0",
|
"ng-packagr": "^17.3.0",
|
||||||
"prettier": "^2.8.4",
|
"prettier": "^2.8.4",
|
||||||
"rxjs": "~7.5.0",
|
"rxjs": "~6.5.3",
|
||||||
"ts-node": "~10.9.1",
|
"ts-node": "~10.9.1",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"typescript": "~4.6.2",
|
"typescript": "~5.4.5",
|
||||||
"zone.js": "~0.11.4"
|
"zone.js": "~0.11.4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|||||||
@@ -8,26 +8,65 @@ export default defineExportTemplate(async ({
|
|||||||
getSvg,
|
getSvg,
|
||||||
deprecated,
|
deprecated,
|
||||||
deprecationReason,
|
deprecationReason,
|
||||||
|
aliases = [],
|
||||||
|
toPascalCase,
|
||||||
}) => {
|
}) => {
|
||||||
const svgContents = await getSvg();
|
const svgContents = await getSvg();
|
||||||
const svgBase64 = base64SVG(svgContents);
|
const svgBase64 = base64SVG(svgContents);
|
||||||
|
const angularComponentName = `Lucide${componentName}`;
|
||||||
|
const selectors = [`svg[lucide${toPascalCase(iconName)}]`];
|
||||||
|
const aliasComponentNames: string[] = [];
|
||||||
|
for (const alias of aliases) {
|
||||||
|
const aliasName = typeof alias === 'string' ? alias : alias.name;
|
||||||
|
const aliasComponentName = `Lucide${toPascalCase(aliasName)}`;
|
||||||
|
const aliasSelector = `svg[lucide${toPascalCase(aliasName)}]`;
|
||||||
|
if (!selectors.includes(aliasSelector)) {
|
||||||
|
selectors.push(aliasSelector);
|
||||||
|
}
|
||||||
|
if (aliasComponentName !== angularComponentName && !aliasComponentNames.includes(aliasComponentName)) {
|
||||||
|
aliasComponentNames.push(aliasComponentName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return `\
|
return `\
|
||||||
import { LucideIconData } from './types';
|
import { LucideIconData } from './types';
|
||||||
|
import { LucideIcon } from '../lib/lucide-icon.component';
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @component @name ${componentName}
|
* @component @name ${componentName}
|
||||||
* @description Lucide SVG icon component, renders SVG Element with children.
|
* @description Lucide SVG icon component, renders SVG Element with children.
|
||||||
*
|
*
|
||||||
* @preview  - https://lucide.dev/icons/${iconName}
|
* @preview  - https://lucide.dev/icons/${iconName}
|
||||||
* @see https://lucide.dev/guide/packages/lucide-vue-next - Documentation
|
* @see https://lucide.dev/guide/packages/lucide-angular - Documentation
|
||||||
*
|
*
|
||||||
* @param {Object} props - Lucide icons props and any valid SVG attribute
|
* @param {Object} props - Lucide icons props and any valid SVG attribute
|
||||||
* @returns {FunctionalComponent} Vue component
|
|
||||||
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
* ${deprecated ? `@deprecated ${deprecationReason}` : ''}
|
||||||
*/
|
*/
|
||||||
const ${componentName}: LucideIconData = ${JSON.stringify(children)}; //eslint-disable-line no-shadow-restricted-names
|
@Component({
|
||||||
|
selector: '${selectors.join(', ')}',
|
||||||
|
template: '',
|
||||||
|
standalone: true,
|
||||||
|
})
|
||||||
|
export class ${angularComponentName} extends LucideIcon {
|
||||||
|
static iconData: LucideIconData = ${JSON.stringify(children)};
|
||||||
|
static iconName = '${iconName}';
|
||||||
|
override get icon() {
|
||||||
|
return ${angularComponentName}.iconData;
|
||||||
|
}
|
||||||
|
override get name() {
|
||||||
|
return ${angularComponentName}.iconName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default ${componentName};
|
${aliasComponentNames.map(([aliasComponentName]) => {
|
||||||
|
return `
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
* @see ${angularComponentName}
|
||||||
|
*/
|
||||||
|
export const ${aliasComponentName} = ${angularComponentName};
|
||||||
|
`;
|
||||||
|
}).join(`\n\n`)}
|
||||||
`;
|
`;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
export * from './aliases';
|
|
||||||
export * from './prefixed';
|
|
||||||
export * from './suffixed';
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"ngPackage": {
|
|
||||||
"dest": "dist",
|
|
||||||
"lib": {
|
|
||||||
"entryFile": "../public-api.ts"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/** @deprecated Use the injection token LUCIDE_ICONS instead. Will be removed in v1.0. */
|
|
||||||
export class Icons {
|
|
||||||
constructor(private icons: object) {}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import { ModuleWithProviders, NgModule, Optional } from '@angular/core';
|
|
||||||
import { LucideAngularComponent } from './lucide-angular.component';
|
|
||||||
import { LucideIcons } from '../icons/types';
|
|
||||||
import { LUCIDE_ICONS, LucideIconProvider } from './lucide-icon.provider';
|
|
||||||
import { Icons } from './icons.provider';
|
|
||||||
|
|
||||||
const legacyIconProviderFactory = (icons?: LucideIcons) => {
|
|
||||||
return new LucideIconProvider(icons ?? {});
|
|
||||||
};
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [LucideAngularComponent],
|
|
||||||
imports: [],
|
|
||||||
exports: [LucideAngularComponent],
|
|
||||||
})
|
|
||||||
export class LucideAngularModule {
|
|
||||||
static pick(icons: LucideIcons): ModuleWithProviders<LucideAngularModule> {
|
|
||||||
return {
|
|
||||||
ngModule: LucideAngularModule,
|
|
||||||
providers: [
|
|
||||||
{ provide: LUCIDE_ICONS, multi: true, useValue: new LucideIconProvider(icons) },
|
|
||||||
{
|
|
||||||
provide: LUCIDE_ICONS,
|
|
||||||
multi: true,
|
|
||||||
useFactory: legacyIconProviderFactory,
|
|
||||||
deps: [[new Optional(), Icons]],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +1,19 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { LucideAngularModule } from './lucide-angular.module';
|
import { formatFixed, LucideIcon } from './lucide-icon.component';
|
||||||
import { formatFixed, LucideAngularComponent } from './lucide-angular.component';
|
|
||||||
import defaultAttributes from '../icons/constants/default-attributes';
|
import defaultAttributes from '../icons/constants/default-attributes';
|
||||||
import { LucideIcons } from '../icons/types';
|
import { LucideIconData } from '../icons/types';
|
||||||
|
|
||||||
describe('LucideAngularComponent', () => {
|
describe('LucideAngularComponent', () => {
|
||||||
let testHostComponent: TestHostComponent;
|
let testHostComponent: TestHostComponent;
|
||||||
let testHostFixture: ComponentFixture<TestHostComponent>;
|
let testHostFixture: ComponentFixture<TestHostComponent>;
|
||||||
const getSvgAttribute = (attr: string) =>
|
const getSvgAttribute = (attr: string) =>
|
||||||
testHostFixture.nativeElement.querySelector('svg').getAttribute(attr);
|
testHostFixture.nativeElement.querySelector('svg').getAttribute(attr);
|
||||||
const testIcons: LucideIcons = {
|
const testIcon: LucideIconData = [['polyline', { points: '1 1 22 22' }]];
|
||||||
Demo: [['polyline', { points: '1 1 22 22' }]],
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [LucideAngularComponent, TestHostComponent],
|
declarations: [LucideIcon, TestHostComponent],
|
||||||
imports: [LucideAngularModule.pick(testIcons)],
|
imports: [],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
testHostFixture = TestBed.createComponent(TestHostComponent);
|
testHostFixture = TestBed.createComponent(TestHostComponent);
|
||||||
testHostComponent = testHostFixture.componentInstance;
|
testHostComponent = testHostFixture.componentInstance;
|
||||||
@@ -63,7 +59,7 @@ describe('LucideAngularComponent', () => {
|
|||||||
testHostComponent.setAbsoluteStrokeWidth(true);
|
testHostComponent.setAbsoluteStrokeWidth(true);
|
||||||
testHostFixture.detectChanges();
|
testHostFixture.detectChanges();
|
||||||
expect(getSvgAttribute('stroke-width')).toBe(
|
expect(getSvgAttribute('stroke-width')).toBe(
|
||||||
formatFixed(strokeWidth / (size / defaultAttributes.height)),
|
formatFixed(strokeWidth / (size / defaultAttributes.height))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -71,6 +67,7 @@ describe('LucideAngularComponent', () => {
|
|||||||
selector: 'lucide-spec-host-component',
|
selector: 'lucide-spec-host-component',
|
||||||
template: ` <i-lucide
|
template: ` <i-lucide
|
||||||
name="demo"
|
name="demo"
|
||||||
|
[img]="testIcon"
|
||||||
class="my-icon"
|
class="my-icon"
|
||||||
[color]="color"
|
[color]="color"
|
||||||
[size]="size"
|
[size]="size"
|
||||||
@@ -83,6 +80,7 @@ describe('LucideAngularComponent', () => {
|
|||||||
size?: number;
|
size?: number;
|
||||||
strokeWidth?: number;
|
strokeWidth?: number;
|
||||||
absoluteStrokeWidth = true;
|
absoluteStrokeWidth = true;
|
||||||
|
readonly testIcon = testIcon;
|
||||||
|
|
||||||
setColor(color: string): void {
|
setColor(color: string): void {
|
||||||
this.color = color;
|
this.color = color;
|
||||||
@@ -5,12 +5,13 @@ import {
|
|||||||
Inject,
|
Inject,
|
||||||
Input,
|
Input,
|
||||||
OnChanges,
|
OnChanges,
|
||||||
|
OnInit,
|
||||||
Renderer2,
|
Renderer2,
|
||||||
SimpleChange,
|
SimpleChange,
|
||||||
|
Type,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { LucideIconData } from '../icons/types';
|
import { LucideIconData } from '../icons/types';
|
||||||
import defaultAttributes from '../icons/constants/default-attributes';
|
import defaultAttributes from '../icons/constants/default-attributes';
|
||||||
import { LUCIDE_ICONS, LucideIconProviderInterface } from './lucide-icon.provider';
|
|
||||||
import { LucideIconConfig } from './lucide-icon.config';
|
import { LucideIconConfig } from './lucide-icon.config';
|
||||||
|
|
||||||
interface TypedChange<T> extends SimpleChange {
|
interface TypedChange<T> extends SimpleChange {
|
||||||
@@ -22,7 +23,7 @@ type SvgAttributes = { [key: string]: string | number };
|
|||||||
|
|
||||||
type LucideAngularComponentChanges = {
|
type LucideAngularComponentChanges = {
|
||||||
name?: TypedChange<string | LucideIconData>;
|
name?: TypedChange<string | LucideIconData>;
|
||||||
img?: TypedChange<LucideIconData | undefined>;
|
icon?: TypedChange<LucideIconData | undefined>;
|
||||||
color?: TypedChange<string>;
|
color?: TypedChange<string>;
|
||||||
size?: TypedChange<number>;
|
size?: TypedChange<number>;
|
||||||
strokeWidth?: TypedChange<number>;
|
strokeWidth?: TypedChange<number>;
|
||||||
@@ -34,24 +35,50 @@ export function formatFixed(number: number, decimals = 3): string {
|
|||||||
return parseFloat(number.toFixed(decimals)).toString(10);
|
return parseFloat(number.toFixed(decimals)).toString(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type LucideIconComponentType = Type<LucideIcon> & { iconData: LucideIconData; name: string };
|
||||||
|
|
||||||
|
function isLucideIconComponent(icon: unknown): icon is LucideIconComponentType {
|
||||||
|
return (
|
||||||
|
icon instanceof Type &&
|
||||||
|
'iconData' in icon &&
|
||||||
|
Array.isArray(icon.iconData) &&
|
||||||
|
'iconName' in icon &&
|
||||||
|
typeof icon.iconName === 'string'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'lucide-angular, lucide-icon, i-lucide, span-lucide',
|
// eslint-disable-next-line @angular-eslint/component-selector
|
||||||
|
selector: 'svg[lucideIcon]',
|
||||||
template: '<ng-content></ng-content>',
|
template: '<ng-content></ng-content>',
|
||||||
|
standalone: true,
|
||||||
})
|
})
|
||||||
export class LucideAngularComponent implements OnChanges {
|
// eslint-disable-next-line @angular-eslint/component-class-suffix
|
||||||
|
export class LucideIcon implements OnInit, OnChanges {
|
||||||
@Input() class?: string;
|
@Input() class?: string;
|
||||||
@Input() name?: string | LucideIconData;
|
_name?: string;
|
||||||
@Input() img?: LucideIconData;
|
@Input() set name(name: string | undefined) {
|
||||||
|
this._name = name;
|
||||||
|
}
|
||||||
|
get name() {
|
||||||
|
return this._name;
|
||||||
|
}
|
||||||
|
_icon?: LucideIconData | LucideIconComponentType | null;
|
||||||
|
@Input('lucideIcon') set icon(icon: LucideIconData | LucideIconComponentType | null | undefined) {
|
||||||
|
this._icon = icon;
|
||||||
|
}
|
||||||
|
get icon() {
|
||||||
|
return this._icon;
|
||||||
|
}
|
||||||
@Input() color?: string;
|
@Input() color?: string;
|
||||||
@Input() absoluteStrokeWidth = false;
|
@Input() absoluteStrokeWidth = false;
|
||||||
defaultSize: number;
|
defaultSize: number;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(ElementRef) private elem: ElementRef,
|
@Inject(ElementRef) protected elem: ElementRef,
|
||||||
@Inject(Renderer2) private renderer: Renderer2,
|
@Inject(Renderer2) protected renderer: Renderer2,
|
||||||
@Inject(ChangeDetectorRef) private changeDetector: ChangeDetectorRef,
|
@Inject(ChangeDetectorRef) protected changeDetector: ChangeDetectorRef,
|
||||||
@Inject(LUCIDE_ICONS) private iconProviders: LucideIconProviderInterface[],
|
@Inject(LucideIconConfig) protected iconConfig: LucideIconConfig
|
||||||
@Inject(LucideIconConfig) private iconConfig: LucideIconConfig,
|
|
||||||
) {
|
) {
|
||||||
this.defaultSize = defaultAttributes.height;
|
this.defaultSize = defaultAttributes.height;
|
||||||
}
|
}
|
||||||
@@ -84,40 +111,37 @@ export class LucideAngularComponent implements OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.buildIcon();
|
||||||
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: LucideAngularComponentChanges): void {
|
ngOnChanges(changes: LucideAngularComponentChanges): void {
|
||||||
if (
|
if (
|
||||||
changes.name ||
|
changes.name ||
|
||||||
changes.img ||
|
changes.icon ||
|
||||||
changes.color ||
|
changes.color ||
|
||||||
changes.size ||
|
changes.size ||
|
||||||
changes.absoluteStrokeWidth ||
|
changes.absoluteStrokeWidth ||
|
||||||
changes.strokeWidth ||
|
changes.strokeWidth ||
|
||||||
changes.class
|
changes.class
|
||||||
) {
|
) {
|
||||||
this.color = this.color ?? this.iconConfig.color;
|
this.buildIcon();
|
||||||
this.size = this.parseNumber(this.size ?? this.iconConfig.size);
|
|
||||||
this.strokeWidth = this.parseNumber(this.strokeWidth ?? this.iconConfig.strokeWidth);
|
|
||||||
this.absoluteStrokeWidth = this.absoluteStrokeWidth ?? this.iconConfig.absoluteStrokeWidth;
|
|
||||||
const nameOrIcon = this.img ?? this.name;
|
|
||||||
if (typeof nameOrIcon === 'string') {
|
|
||||||
const icoOfName = this.getIcon(this.toPascalCase(nameOrIcon));
|
|
||||||
if (icoOfName) {
|
|
||||||
this.replaceElement(icoOfName);
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
`The "${nameOrIcon}" icon has not been provided by any available icon providers.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if (Array.isArray(nameOrIcon)) {
|
|
||||||
this.replaceElement(nameOrIcon);
|
|
||||||
} else {
|
|
||||||
throw new Error(`No icon name or image has been provided.`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.changeDetector.markForCheck();
|
this.changeDetector.markForCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildIcon(): void {
|
||||||
|
this.color = this.color ?? this.iconConfig.color;
|
||||||
|
this.size = this.parseNumber(this.size ?? this.iconConfig.size);
|
||||||
|
this.strokeWidth = this.parseNumber(this.strokeWidth ?? this.iconConfig.strokeWidth);
|
||||||
|
this.absoluteStrokeWidth = this.absoluteStrokeWidth ?? this.iconConfig.absoluteStrokeWidth;
|
||||||
|
console.log('Hello, my name is ', this.name, ' my icon is ', this.icon);
|
||||||
|
if (this.icon) {
|
||||||
|
this.replaceElement(isLucideIconComponent(this.icon) ? this.icon.iconData : this.icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
replaceElement(img: LucideIconData): void {
|
replaceElement(img: LucideIconData): void {
|
||||||
const attributes = {
|
const attributes = {
|
||||||
...defaultAttributes,
|
...defaultAttributes,
|
||||||
@@ -128,7 +152,10 @@ export class LucideAngularComponent implements OnChanges {
|
|||||||
? formatFixed(this.strokeWidth / (this.size / this.defaultSize))
|
? formatFixed(this.strokeWidth / (this.size / this.defaultSize))
|
||||||
: this.strokeWidth.toString(10),
|
: this.strokeWidth.toString(10),
|
||||||
};
|
};
|
||||||
const icoElement = this.createElement(['svg', attributes, img]);
|
const icoElement = this.elem.nativeElement;
|
||||||
|
for (const [name, value] of Object.entries(attributes)) {
|
||||||
|
icoElement.setAttribute(name, value);
|
||||||
|
}
|
||||||
icoElement.classList.add('lucide');
|
icoElement.classList.add('lucide');
|
||||||
if (typeof this.name === 'string') {
|
if (typeof this.name === 'string') {
|
||||||
icoElement.classList.add(`lucide-${this.name.replace('_', '-')}`);
|
icoElement.classList.add(`lucide-${this.name.replace('_', '-')}`);
|
||||||
@@ -138,24 +165,19 @@ export class LucideAngularComponent implements OnChanges {
|
|||||||
...this.class
|
...this.class
|
||||||
.split(/ /)
|
.split(/ /)
|
||||||
.map((a) => a.trim())
|
.map((a) => a.trim())
|
||||||
.filter((a) => a.length > 0),
|
.filter((a) => a.length > 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const childElements = this.elem.nativeElement.childNodes;
|
for (const child of icoElement.children) {
|
||||||
for (const child of childElements) {
|
|
||||||
this.renderer.removeChild(this.elem.nativeElement, child);
|
this.renderer.removeChild(this.elem.nativeElement, child);
|
||||||
}
|
}
|
||||||
this.renderer.appendChild(this.elem.nativeElement, icoElement);
|
for (const node of img) {
|
||||||
|
const childElement = this.createElement(node);
|
||||||
|
this.renderer.appendChild(icoElement, childElement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toPascalCase(str: string): string {
|
protected parseNumber(value: string | number): number {
|
||||||
return str.replace(
|
|
||||||
/(\w)([a-z0-9]*)(_|-|\s*)/g,
|
|
||||||
(g0, g1, g2) => g1.toUpperCase() + g2.toLowerCase(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private parseNumber(value: string | number): number {
|
|
||||||
if (typeof value === 'string') {
|
if (typeof value === 'string') {
|
||||||
const parsedValue = parseInt(value, 10);
|
const parsedValue = parseInt(value, 10);
|
||||||
if (isNaN(parsedValue)) {
|
if (isNaN(parsedValue)) {
|
||||||
@@ -166,21 +188,10 @@ export class LucideAngularComponent implements OnChanges {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getIcon(name: string): LucideIconData | null {
|
protected createElement([tag, attrs, children = []]: readonly [
|
||||||
for (const iconProvider of Array.isArray(this.iconProviders)
|
|
||||||
? this.iconProviders
|
|
||||||
: [this.iconProviders]) {
|
|
||||||
if (iconProvider.hasIcon(name)) {
|
|
||||||
return iconProvider.getIcon(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private createElement([tag, attrs, children = []]: readonly [
|
|
||||||
string,
|
string,
|
||||||
SvgAttributes,
|
SvgAttributes,
|
||||||
LucideIconData?,
|
LucideIconData?
|
||||||
]) {
|
]) {
|
||||||
const element = this.renderer.createElement(tag, 'http://www.w3.org/2000/svg');
|
const element = this.renderer.createElement(tag, 'http://www.w3.org/2000/svg');
|
||||||
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import { LucideIconData, LucideIcons } from '../icons/types';
|
|
||||||
import { InjectionToken } from '@angular/core';
|
|
||||||
|
|
||||||
export interface LucideIconProviderInterface {
|
|
||||||
hasIcon(name: string): boolean;
|
|
||||||
|
|
||||||
getIcon(name: string): LucideIconData | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const LUCIDE_ICONS = new InjectionToken<LucideIconProviderInterface>('LucideIcons', {
|
|
||||||
factory: () => new LucideIconProvider({}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export class LucideIconProvider implements LucideIconProviderInterface {
|
|
||||||
constructor(private icons: LucideIcons) {}
|
|
||||||
|
|
||||||
getIcon(name: string): LucideIconData | null {
|
|
||||||
return this.hasIcon(name) ? this.icons[name] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasIcon(name: string): boolean {
|
|
||||||
return typeof this.icons === 'object' && name in this.icons;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
import * as icons from './icons/lucide-icons';
|
import * as icons from './icons/lucide-icons';
|
||||||
|
|
||||||
export * from './lib/lucide-angular.component';
|
export * from './lib/lucide-icon.component';
|
||||||
export * from './lib/lucide-angular.module';
|
|
||||||
export * from './lib/lucide-icon.config';
|
export * from './lib/lucide-icon.config';
|
||||||
export * from './lib/lucide-icon.provider';
|
|
||||||
export * from './icons/lucide-icons';
|
export * from './icons/lucide-icons';
|
||||||
export * from './icons/types';
|
export * from './icons/types';
|
||||||
export * from './aliases';
|
|
||||||
export { icons };
|
export { icons };
|
||||||
|
|||||||
@@ -24,7 +24,9 @@
|
|||||||
"author": "Eric Fennis",
|
"author": "Eric Fennis",
|
||||||
"amdName": "lucide-preact",
|
"amdName": "lucide-preact",
|
||||||
"main": "dist/cjs/lucide-preact.js",
|
"main": "dist/cjs/lucide-preact.js",
|
||||||
|
"main:umd": "dist/umd/lucide-preact.js",
|
||||||
"module": "dist/esm/lucide-preact.js",
|
"module": "dist/esm/lucide-preact.js",
|
||||||
|
"unpkg": "dist/umd/lucide-preact.min.js",
|
||||||
"typings": "dist/lucide-preact.d.ts",
|
"typings": "dist/lucide-preact.d.ts",
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
@@ -44,7 +46,7 @@
|
|||||||
"@lucide/rollup-plugins": "workspace:*",
|
"@lucide/rollup-plugins": "workspace:*",
|
||||||
"@lucide/shared": "workspace:*",
|
"@lucide/shared": "workspace:*",
|
||||||
"@preact/preset-vite": "^2.10.2",
|
"@preact/preset-vite": "^2.10.2",
|
||||||
"@testing-library/jest-dom": "^6.6.3",
|
"@testing-library/jest-dom": "^6.1.4",
|
||||||
"@testing-library/preact": "^3.2.3",
|
"@testing-library/preact": "^3.2.3",
|
||||||
"jest-serializer-html": "^7.1.0",
|
"jest-serializer-html": "^7.1.0",
|
||||||
"preact": "^10.19.2",
|
"preact": "^10.19.2",
|
||||||
|
|||||||
@@ -7,6 +7,17 @@ const outputFileName = 'lucide-preact';
|
|||||||
const outputDir = 'dist';
|
const outputDir = 'dist';
|
||||||
const inputs = [`src/lucide-preact.ts`];
|
const inputs = [`src/lucide-preact.ts`];
|
||||||
const bundles = [
|
const bundles = [
|
||||||
|
{
|
||||||
|
format: 'umd',
|
||||||
|
inputs,
|
||||||
|
outputDir,
|
||||||
|
minify: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: 'umd',
|
||||||
|
inputs,
|
||||||
|
outputDir,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
inputs,
|
inputs,
|
||||||
@@ -21,7 +32,7 @@ const bundles = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const configs = bundles
|
const configs = bundles
|
||||||
.map(({ inputs, outputDir, format, preserveModules }) =>
|
.map(({ inputs, outputDir, format, minify, preserveModules }) =>
|
||||||
inputs.map((input) => ({
|
inputs.map((input) => ({
|
||||||
input,
|
input,
|
||||||
plugins: plugins({ pkg, minify }),
|
plugins: plugins({ pkg, minify }),
|
||||||
@@ -33,7 +44,7 @@ const configs = bundles
|
|||||||
dir: `${outputDir}/${format}`,
|
dir: `${outputDir}/${format}`,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
file: `${outputDir}/${format}/${outputFileName}.js`,
|
file: `${outputDir}/${format}/${outputFileName}${minify ? '.min' : ''}.js`,
|
||||||
}),
|
}),
|
||||||
preserveModules,
|
preserveModules,
|
||||||
format,
|
format,
|
||||||
|
|||||||
@@ -24,7 +24,9 @@
|
|||||||
"author": "Eric Fennis",
|
"author": "Eric Fennis",
|
||||||
"amdName": "lucide-react-native",
|
"amdName": "lucide-react-native",
|
||||||
"main": "dist/cjs/lucide-react-native.js",
|
"main": "dist/cjs/lucide-react-native.js",
|
||||||
|
"main:umd": "dist/umd/lucide-react-native.js",
|
||||||
"module": "dist/esm/lucide-react-native.js",
|
"module": "dist/esm/lucide-react-native.js",
|
||||||
|
"unpkg": "dist/umd/lucide-react-native.min.js",
|
||||||
"typings": "dist/lucide-react-native.d.ts",
|
"typings": "dist/lucide-react-native.d.ts",
|
||||||
"react-native": "dist/esm/lucide-react-native.js",
|
"react-native": "dist/esm/lucide-react-native.js",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
@@ -44,7 +46,7 @@
|
|||||||
"@lucide/rollup-plugins": "workspace:*",
|
"@lucide/rollup-plugins": "workspace:*",
|
||||||
"@lucide/build-icons": "workspace:*",
|
"@lucide/build-icons": "workspace:*",
|
||||||
"@lucide/shared": "workspace:*",
|
"@lucide/shared": "workspace:*",
|
||||||
"@testing-library/jest-dom": "^6.6.3",
|
"@testing-library/jest-dom": "^6.1.6",
|
||||||
"@testing-library/react": "^14.1.2",
|
"@testing-library/react": "^14.1.2",
|
||||||
"@types/prop-types": "^15.7.5",
|
"@types/prop-types": "^15.7.5",
|
||||||
"@types/react": "^18.0.21",
|
"@types/react": "^18.0.21",
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ const bundles = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const configs = bundles
|
const configs = bundles
|
||||||
.map(({ inputs, outputDir, format, preserveModules }) =>
|
.map(({ inputs, outputDir, format, minify, preserveModules }) =>
|
||||||
inputs.map((input) => ({
|
inputs.map((input) => ({
|
||||||
input,
|
input,
|
||||||
plugins: plugins({ pkg }),
|
plugins: plugins({ pkg, minify }),
|
||||||
external: ['react', 'react-native-svg'],
|
external: ['react', 'react-native-svg'],
|
||||||
output: {
|
output: {
|
||||||
name: packageName,
|
name: packageName,
|
||||||
@@ -35,7 +35,7 @@ const configs = bundles
|
|||||||
exports: 'auto',
|
exports: 'auto',
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
file: `${outputDir}/${format}/${outputFileName}.js`,
|
file: `${outputDir}/${format}/${outputFileName}${minify ? '.min' : ''}.js`,
|
||||||
}),
|
}),
|
||||||
format,
|
format,
|
||||||
preserveModules,
|
preserveModules,
|
||||||
|
|||||||
@@ -24,7 +24,9 @@
|
|||||||
"author": "Eric Fennis",
|
"author": "Eric Fennis",
|
||||||
"amdName": "lucide-react",
|
"amdName": "lucide-react",
|
||||||
"main": "dist/cjs/lucide-react.js",
|
"main": "dist/cjs/lucide-react.js",
|
||||||
|
"main:umd": "dist/umd/lucide-react.js",
|
||||||
"module": "dist/esm/lucide-react.js",
|
"module": "dist/esm/lucide-react.js",
|
||||||
|
"unpkg": "dist/umd/lucide-react.min.js",
|
||||||
"typings": "dist/lucide-react.d.ts",
|
"typings": "dist/lucide-react.d.ts",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"files": [
|
"files": [
|
||||||
@@ -52,7 +54,7 @@
|
|||||||
"@lucide/build-icons": "workspace:*",
|
"@lucide/build-icons": "workspace:*",
|
||||||
"@lucide/rollup-plugins": "workspace:*",
|
"@lucide/rollup-plugins": "workspace:*",
|
||||||
"@lucide/shared": "workspace:*",
|
"@lucide/shared": "workspace:*",
|
||||||
"@testing-library/jest-dom": "^6.6.3",
|
"@testing-library/jest-dom": "^6.1.6",
|
||||||
"@testing-library/react": "^14.1.2",
|
"@testing-library/react": "^14.1.2",
|
||||||
"@types/react": "^18.2.37",
|
"@types/react": "^18.2.37",
|
||||||
"@vitejs/plugin-react": "^4.4.1",
|
"@vitejs/plugin-react": "^4.4.1",
|
||||||
|
|||||||
@@ -10,6 +10,17 @@ const packageName = 'LucideReact';
|
|||||||
const outputFileName = 'lucide-react';
|
const outputFileName = 'lucide-react';
|
||||||
const inputs = [`src/lucide-react.ts`];
|
const inputs = [`src/lucide-react.ts`];
|
||||||
const bundles = [
|
const bundles = [
|
||||||
|
{
|
||||||
|
format: 'umd',
|
||||||
|
inputs,
|
||||||
|
outputDir: 'dist/umd',
|
||||||
|
minify: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: 'umd',
|
||||||
|
inputs,
|
||||||
|
outputDir: 'dist/umd',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
inputs,
|
inputs,
|
||||||
@@ -67,7 +78,7 @@ const configs = bundles
|
|||||||
dir: outputDir,
|
dir: outputDir,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
file: outputFile ?? `${outputDir}/${outputFileName}.js`,
|
file: outputFile ?? `${outputDir}/${outputFileName}${minify ? '.min' : ''}.js`,
|
||||||
}),
|
}),
|
||||||
paths,
|
paths,
|
||||||
entryFileNames,
|
entryFileNames,
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
"@lucide/shared": "workspace:*",
|
"@lucide/shared": "workspace:*",
|
||||||
"@rollup/plugin-babel": "^6.0.4",
|
"@rollup/plugin-babel": "^6.0.4",
|
||||||
"@solidjs/testing-library": "^0.8.10",
|
"@solidjs/testing-library": "^0.8.10",
|
||||||
"@testing-library/jest-dom": "^6.6.3",
|
"@testing-library/jest-dom": "^6.4.2",
|
||||||
"babel-preset-solid": "^1.8.12",
|
"babel-preset-solid": "^1.8.12",
|
||||||
"jest-serializer-html": "^7.1.0",
|
"jest-serializer-html": "^7.1.0",
|
||||||
"rollup": "^4.53.3",
|
"rollup": "^4.53.3",
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
"@lucide/helpers": "workspace:*",
|
"@lucide/helpers": "workspace:*",
|
||||||
"@sveltejs/package": "^2.2.3",
|
"@sveltejs/package": "^2.2.3",
|
||||||
"@sveltejs/vite-plugin-svelte": "^2.4.2",
|
"@sveltejs/vite-plugin-svelte": "^2.4.2",
|
||||||
"@testing-library/jest-dom": "^6.6.3",
|
"@testing-library/jest-dom": "^6.1.4",
|
||||||
"@testing-library/svelte": "^4.0.2",
|
"@testing-library/svelte": "^4.0.2",
|
||||||
"@tsconfig/svelte": "^5.0.0",
|
"@tsconfig/svelte": "^5.0.0",
|
||||||
"jest-serializer-html": "^7.1.0",
|
"jest-serializer-html": "^7.1.0",
|
||||||
|
|||||||
@@ -25,7 +25,9 @@
|
|||||||
"amdName": "lucide-vue-next",
|
"amdName": "lucide-vue-next",
|
||||||
"source": "build/lucide-vue-next.js",
|
"source": "build/lucide-vue-next.js",
|
||||||
"main": "dist/cjs/lucide-vue-next.js",
|
"main": "dist/cjs/lucide-vue-next.js",
|
||||||
|
"main:umd": "dist/umd/lucide-vue-next.js",
|
||||||
"module": "dist/esm/lucide-vue-next.js",
|
"module": "dist/esm/lucide-vue-next.js",
|
||||||
|
"unpkg": "dist/umd/lucide-vue-next.min.js",
|
||||||
"typings": "dist/lucide-vue-next.d.ts",
|
"typings": "dist/lucide-vue-next.d.ts",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"files": [
|
"files": [
|
||||||
@@ -46,7 +48,7 @@
|
|||||||
"@lucide/build-icons": "workspace:*",
|
"@lucide/build-icons": "workspace:*",
|
||||||
"@lucide/rollup-plugins": "workspace:*",
|
"@lucide/rollup-plugins": "workspace:*",
|
||||||
"@lucide/shared": "workspace:*",
|
"@lucide/shared": "workspace:*",
|
||||||
"@testing-library/jest-dom": "^6.6.3",
|
"@testing-library/jest-dom": "^6.1.6",
|
||||||
"@testing-library/vue": "^8.1.0",
|
"@testing-library/vue": "^8.1.0",
|
||||||
"@vitejs/plugin-vue": "^6.0.2",
|
"@vitejs/plugin-vue": "^6.0.2",
|
||||||
"@vue/test-utils": "2.4.6",
|
"@vue/test-utils": "2.4.6",
|
||||||
|
|||||||
@@ -7,6 +7,17 @@ const outputFileName = 'lucide-vue-next';
|
|||||||
const outputDir = 'dist';
|
const outputDir = 'dist';
|
||||||
const inputs = ['src/lucide-vue-next.ts'];
|
const inputs = ['src/lucide-vue-next.ts'];
|
||||||
const bundles = [
|
const bundles = [
|
||||||
|
{
|
||||||
|
format: 'umd',
|
||||||
|
inputs,
|
||||||
|
outputDir,
|
||||||
|
minify: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: 'umd',
|
||||||
|
inputs,
|
||||||
|
outputDir,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
inputs,
|
inputs,
|
||||||
@@ -33,7 +44,7 @@ const configs = bundles
|
|||||||
dir: `${outputDir}/${format}`,
|
dir: `${outputDir}/${format}`,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
file: `${outputDir}/${format}/${outputFileName}.js`,
|
file: `${outputDir}/${format}/${outputFileName}${minify ? '.min' : ''}.js`,
|
||||||
}),
|
}),
|
||||||
format,
|
format,
|
||||||
preserveModules,
|
preserveModules,
|
||||||
|
|||||||