Merge branch 'lucide-angular-fix-structure'

This commit is contained in:
Eric Fennis
2021-04-22 20:47:56 +02:00
35 changed files with 189 additions and 230 deletions

1
.gitignore vendored
View File

@@ -10,3 +10,4 @@ coverage
stats
*.log
packages/**/src/icons/*.js
packages/**/src/icons/*.ts

View File

@@ -93,7 +93,7 @@ yarn add lucide-angular
npm install lucide-angular
```
For more details, see the [documentation](https://github.com/lucide-icons/lucide/tree/master/packages/lucide-angular/projects/lucide-angular#lucide-angular).
For more details, see the [documentation](https://github.com/lucide-icons/lucide/tree/packages/lucide-angular#lucide-angular).
### Figma

View File

@@ -48,4 +48,4 @@ Thumbs.db
#npm-yarn
package-lock.json
yarn.lock
src/createElement.js

View File

@@ -0,0 +1,15 @@
ISC License
Copyright (c) 2020, Lucide Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -22,9 +22,9 @@ There are three ways for use this library.
After install `lucide-angular` change content of file `app.component.html` and `app.component.ts`.
``` xml
``` html
<!-- app.component.html -->
<div id="ico"></div>
<div id="lucide-icon"></div>
```
``` js
@@ -39,13 +39,16 @@ import { Activity } from 'lucide-angular/icons';
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
export class AppComponent implements OnInit {
ngOnInit(): void {
const div = document.getElementById('ico');
const div = document.getElementById('lucide-icon');
const elm = createElement(Activity);
elm.setAttribute('color', 'red'); // or set `width`, `height`, `fill`, `stroke-width`, ...
div.appendChild(elm);
if (div) {
div.appendChild(elm);
}
}
}
```
@@ -61,8 +64,7 @@ import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LucideAngularModule } from 'lucide-angular';
import { AlarmCheck, Edit } from 'lucide-angular/icons'; // or import other icons
import { LucideAngularModule, AlarmCheck, Edit } from 'lucide-angular';
@NgModule({
declarations: [
@@ -79,37 +81,12 @@ import { AlarmCheck, Edit } from 'lucide-angular/icons'; // or import other ico
export class AppModule { }
```
``` css
/* app.component.css */
.myicon {
/* Be sure to set these values */
width: 48px;
height: 48px;
/* or other properties like `color`, `fill`, `stroke-width` */
}
```
``` xml
``` html
<!-- app.component.html -->
<lucide-icon name="alarm-check" class="myicon"></lucide-icon>
<lucide-icon name="edit" class="myicon"></lucide-icon>
```
``` js
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
}
```
### Method 3: User __Tag__ with __img__ property
After install `lucide-angular` change content of file `app.component.html`, `app.component.ts`, `app.component.css` and `app.module.ts`.
@@ -138,16 +115,6 @@ import { LucideAngularModule } from 'lucide-angular';
export class AppModule { }
```
``` css
/* app.component.css */
.myicon {
/* Be sure to set these values */
width: 48px;
height: 48px;
/* or other properties like `color`, `fill`, `stroke-width` */
}
```
``` xml
<!-- app.component.html -->
<lucide-icon [img]="ico1" class="myicon"></lucide-icon>
@@ -157,13 +124,14 @@ export class AppModule { }
``` js
// app.component.ts
import { Component } from '@angular/core';
import { Airplay, Circle } from 'lucide-angular/icons';
import { Airplay, Circle } from 'lucide-angular';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
ico1 = Airplay;
ico2 = Circle;
@@ -175,6 +143,7 @@ export class AppComponent {
### Import all icons
In `Method 2`: import all icons in `app.module.ts` by:
``` js
...
import { icons } from 'lucide-angular/icons';
@@ -182,10 +151,13 @@ import { icons } from 'lucide-angular/icons';
LucideAngularModule.pick(icons)
....
```
### Tags
You can use the following tags instead of `lucide-icon`:
* lucide-angular
* i-lucide
* span-lucide
- lucide-angular
- i-lucide
- span-lucide
All of the above are the same

View File

@@ -1,40 +1,40 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"$schema": "../../node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"newProjectRoot": "",
"projects": {
"lucide-angular": {
"projectType": "library",
"root": "projects/lucide-angular",
"sourceRoot": "projects/lucide-angular/src",
"root": "",
"sourceRoot": "src",
"prefix": "lib",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:ng-packagr",
"options": {
"tsConfig": "projects/lucide-angular/tsconfig.lib.json",
"project": "projects/lucide-angular/ng-package.json"
"tsConfig": "tsconfig.lib.json",
"project": "ng-package.json"
},
"configurations": {
"production": {
"tsConfig": "projects/lucide-angular/tsconfig.lib.prod.json"
"tsConfig": "tsconfig.lib.prod.json"
}
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "projects/lucide-angular/src/test.ts",
"tsConfig": "projects/lucide-angular/tsconfig.spec.json",
"karmaConfig": "projects/lucide-angular/karma.conf.js"
"main": "src/test.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"projects/lucide-angular/tsconfig.lib.json",
"projects/lucide-angular/tsconfig.spec.json"
"tsconfig.lib.json",
"tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"

View File

@@ -1,8 +1,9 @@
/* eslint-disable import/no-extraneous-dependencies, global-require, func-names */
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
process.env.CHROME_BIN = require('puppeteer').executablePath();
module.exports = function (config) {
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
@@ -11,7 +12,7 @@ module.exports = function (config) {
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma')
require('@angular-devkit/build-angular/plugins/karma'),
],
client: {
jasmine: {
@@ -20,18 +21,15 @@ module.exports = function (config) {
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
clearContext: false, // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
suppressAll: true, // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, '../../coverage/lucide-angular'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
reporters: [{ type: 'html' }, { type: 'text-summary' }],
},
reporters: ['progress', 'kjhtml'],
port: 9876,
@@ -42,10 +40,10 @@ module.exports = function (config) {
customLaunchers: {
ChromeHeadlessCI: {
base: 'ChromeHeadless',
flags: ['--no-sandbox']
}
flags: ['--no-sandbox'],
},
},
singleRun: false,
restartOnFileChange: true
restartOnFileChange: true,
});
};

View File

@@ -0,0 +1,7 @@
{
"$schema": "./node_modules/ng-packagr/ng-package.schema.json",
"dest": "dist",
"lib": {
"entryFile": "src/index.ts"
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "lucide-angular",
"description": "Lucide Angular package, Lucide is a community-run fork of Feather Icons, open for anyone to contribute icons.",
"version": "0.15.0",
"version": "0.15.1-beta.1",
"author": "SMAH1",
"license": "ISC",
"homepage": "https://lucide.dev",
@@ -9,7 +9,7 @@
"repository": {
"type": "git",
"url": "https://github.com/lucide-icons/lucide.git",
"directory": "packages/lucide-vue"
"directory": "packages/lucide-angular"
},
"keywords": [
"Lucide",
@@ -22,26 +22,29 @@
"Font Awesome"
],
"scripts": {
"build": "yarn clean && yarn build:js && yarn build:icons && yarn build:iconsindex && yarn build:ng",
"clean": "rm -rf dist && rm -rf projects/lucide-angular/build",
"build:js": "mkdir -p projects/lucide-angular/build && cp -av ../lucide/src/createElement.js projects/lucide-angular/build/",
"build:icons": "yarn --cwd ../../ build:icons --output=../packages/lucide-angular/projects/lucide-angular/build --templateSrc=../packages/lucide-angular/scripts/exportTemplate && for f in projects/lucide-angular/build/icons/*.js; do mv -- \"$f\" \"${f%.js}.ts\"; done",
"build:iconsindex": "yarn --cwd ../../ babel-node packages/lucide-angular/scripts/buildIconsIndex.js",
"build": "yarn clean && yarn build:icons && yarn build:ng",
"clean": "rm -rf dist && rm -rf ./src/icons/*.ts",
"build:icons": "yarn --cwd ../../ build:icons --output=../packages/lucide-angular/src --templateSrc=../packages/lucide-angular/scripts/exportTemplate --iconFileExtention=.ts --exportFileName=index.ts",
"build:ng": "ng build --prod",
"test:headless": "ng test --no-watch --no-progress --browsers=ChromeHeadlessCI",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
"e2e": "ng e2e",
"postinstall": "ngcc"
},
"dependencies": {
"tslib": "^2.0.0"
},
"peerDependencies": {
"@angular/common": "^11.2.6",
"@angular/core": "^11.2.6"
},
"devDependencies": {
"@angular/common": "~11.2.6",
"@angular/compiler": "~11.2.6",
"@angular/core": "~11.2.6",
"@angular/platform-browser": "~11.2.6",
"@angular/platform-browser-dynamic": "~11.2.6",
"tslib": "^2.0.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1102.5",
"@angular/cli": "~11.2.5",
"@angular/compiler-cli": "~11.2.6",

View File

@@ -1,4 +0,0 @@
export * from './build/icons-index';
import * as icons from './build/icons-index';
export { icons };

View File

@@ -1,7 +0,0 @@
{
"ngPackage": {
"lib": {
"entryFile": "../icons-index.ts"
}
}
}

View File

@@ -1,4 +0,0 @@
export * from './src/lib/lucide-angular.component';
export * from './src/lib/lucide-angular.module';
export * from './lucide';

View File

@@ -1,10 +0,0 @@
export type IconNode = readonly [string, object];
export type IconData = readonly [string, object, IconNode[] ];
export declare const icons: { [key: string]: IconData };
import { default as createElementTmp } from './build/createElement';
export function createElement(ico: IconData): HTMLElement {
return createElementTmp(ico as any);
}

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/lucide-angular",
"lib": {
"entryFile": "./lib-index.ts"
}
}

View File

@@ -1,31 +0,0 @@
{
"name": "lucide-angular",
"description": "Lucide Angular package, Lucide is a community-run fork of Feather Icons, open for anyone to contribute icons.",
"version": "0.15.0",
"author": "SMAH1",
"license": "ISC",
"homepage": "https://lucide.dev",
"bugs": "https://github.com/lucide-icons/lucide/issues",
"repository": {
"type": "git",
"url": "https://github.com/lucide-icons/lucide.git",
"directory": "packages/lucide-vue"
},
"keywords": [
"Lucide",
"Angular",
"Feather",
"Icons",
"Icon",
"Feather Icons",
"Fontawesome",
"Font Awesome"
],
"peerDependencies": {
"@angular/common": "^11.2.6",
"@angular/core": "^11.2.6"
},
"dependencies": {
"tslib": "^2.0.0"
}
}

View File

@@ -1,17 +0,0 @@
{
"extends": "../../tslint.json",
"rules": {
"directive-selector": [
true,
"attribute",
"lib",
"camelCase"
],
"component-selector": [
true,
"element",
"",
"kebab-case"
]
}
}

View File

@@ -1,39 +0,0 @@
import path from 'path';
import {
writeFile,
resetFile,
appendFile,
readSvgDirectory,
} from '../../../scripts/helpers';
const TARGET_DIR = path.join(__dirname, '../projects/lucide-angular/build');
const ICONS_DIR = path.resolve(__dirname, '../../../icons');
const TYPES_FILE_NAME = 'icons-index.ts';
// Generates header of d.ts file include some types and functions
const typeDefinitions = `\
export type IconNode = readonly [string, object];
export type IconData = readonly [string, object, IconNode[] ];
export declare const icons: { [key: string]: IconData };
// Generated icons
`;
resetFile(TYPES_FILE_NAME, TARGET_DIR);
writeFile(typeDefinitions, TYPES_FILE_NAME, TARGET_DIR);
const svgFiles = readSvgDirectory(ICONS_DIR);
svgFiles.forEach(svgFile => {
const kebab = path.basename(svgFile, '.svg');
appendFile(
`export * from './icons/${kebab}';\n`,
TYPES_FILE_NAME,
TARGET_DIR,
);
});
console.log(`Generated ${TYPES_FILE_NAME} file with`, svgFiles.length, 'icons');

View File

@@ -1,10 +1,12 @@
export default ({ componentName, children }) => `
import { IconData } from '../../lucide';
import defaultAttributes from '../../default-attributes';
import { IconData } from './types';
import defaultAttributes from './constants/default-attributes';
export const ${componentName}: IconData = [
const ${componentName}: IconData = [
'svg',
defaultAttributes,
${JSON.stringify(children)}
];
export default ${componentName};
`;

View File

@@ -0,0 +1,26 @@
import { IconData } from '../icons/types'
/**
* Creates a new SVGElement from icon node
* @param {string} tag
* @param {object} attrs
* @param {array} children
* @returns {SVGElement}
*/
export const createElement = ([tag, attrs, children = []]: IconData): SVGElement => {
const element = document.createElementNS('http://www.w3.org/2000/svg', tag);
Object.keys(attrs).forEach(name => {
element.setAttribute(name, attrs[name]);
});
if (children.length) {
children.forEach((child: IconData) => {
const childElement = createElement(child);
element.appendChild(childElement);
});
}
return element;
};

View File

@@ -0,0 +1,8 @@
{
"ngPackage": {
"dest": "dist",
"lib": {
"entryFile": "./index.ts"
}
}
}

View File

@@ -0,0 +1,3 @@
export type IconNode = readonly [string, object];
export type IconData = readonly [string, object, IconNode[]? ];
export type Icons = { [key: string]: IconData }

View File

@@ -0,0 +1,7 @@
import * as icons from './icons';
export * from './lib/lucide-angular.component';
export * from './lib/lucide-angular.module';
export * from './helpers/create-element';
export * from './icons';
export { icons };

View File

@@ -1,6 +1,5 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LucideAngularModule } from './lucide-angular.module';
import { LucideAngularComponent } from './lucide-angular.component';
describe('LucideAngularComponent', () => {

View File

@@ -1,6 +1,7 @@
import { Component, ElementRef, Input, Inject, ChangeDetectorRef, OnChanges, SimpleChanges } from '@angular/core';
import { Icons } from './icons.provider';
import { createElement, IconData } from '../../lucide';
import { IconData } from '../icons/types';
import { createElement } from '../helpers/create-element';
@Component({
selector: 'lucide-angular, lucide-icon, i-lucide, span-lucide',
@@ -9,13 +10,16 @@ import { createElement, IconData } from '../../lucide';
:host {
display: inline-block;
fill: none;
stroke: inherit;
stroke-width: inherit;
stroke: currentColor;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
width: 24px;
height: 24px;
}
`]
})
export class LucideAngularComponent implements OnChanges {
@Input() name!: string;
@Input() img!: IconData;

View File

@@ -1,12 +1,15 @@
import { NgModule, ModuleWithProviders, Optional } from '@angular/core';
import { LucideAngularComponent } from './lucide-angular.component';
import { Icons } from './icons.provider';
import { IconData } from '../../lucide';
import { IconData } from '../icons/types';
@NgModule({
declarations: [LucideAngularComponent],
imports: [
],
exports: [LucideAngularComponent]
})
export class LucideAngularModule {
constructor(@Optional() private icons: Icons) {
if (!this.icons) {

View File

@@ -9,12 +9,13 @@
"downlevelIteration": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowJs": true,
"paths": {
"lucide-angular": [
"dist/lucide-angular/lucide-angular",
"dist/lucide-angular"
]
"dist"
],
"lucide-angular/*": [
"dist/*"
],
},
"moduleResolution": "node",
"importHelpers": true,

View File

@@ -1,8 +1,8 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../tsconfig.json",
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/lib",
"outDir": "./out-tsc/lib",
"target": "es2015",
"declaration": true,
"declarationMap": true,
@@ -17,7 +17,8 @@
"angularCompilerOptions": {
"skipTemplateCodegen": true,
"strictMetadataEmit": true,
"enableResourceInlining": true
"enableResourceInlining": true,
"fullTemplateTypeCheck": true
},
"exclude": [
"src/test.ts",

View File

@@ -1,8 +1,8 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../tsconfig.json",
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"outDir": "./out-tsc/spec",
"types": [
"jasmine"
]

View File

@@ -16,6 +16,18 @@
"deprecation": {
"severity": "warning"
},
"directive-selector": [
true,
"attribute",
"lib",
"camelCase"
],
"component-selector": [
true,
"element",
"",
"kebab-case"
],
"eofline": true,
"import-blacklist": [
true,

View File

@@ -4,7 +4,7 @@ import path from 'path';
import prettier from 'prettier';
import { toPascalCase } from '../helpers';
export default function(iconNodes, outputDirectory, template, { showLog = true }) {
export default function({ iconNodes, outputDirectory, template, showLog = true, iconFileExtention = '.js' }) {
const icons = Object.keys(iconNodes);
const iconsDistDirectory = path.join(outputDirectory, `icons`);
@@ -13,7 +13,7 @@ export default function(iconNodes, outputDirectory, template, { showLog = true }
}
icons.forEach(iconName => {
const location = path.join(iconsDistDirectory, `${iconName}.js`);
const location = path.join(iconsDistDirectory, `${iconName}${iconFileExtention}`);
const componentName = toPascalCase(iconName);
let { children } = iconNodes[iconName];

View File

@@ -12,22 +12,38 @@ const cliArguments = getArgumentOptions(process.argv.slice(2));
const ICONS_DIR = path.resolve(__dirname, '../icons');
const OUTPUT_DIR = path.resolve(__dirname, cliArguments.output || '../build');
const SRC_DIR = path.resolve(__dirname, '../src');
if (!fs.existsSync(OUTPUT_DIR)) {
fs.mkdirSync(OUTPUT_DIR);
}
const {
renderUniqueKey = false,
templateSrc = './templates/defaultIconFileTemplate',
silent = false,
iconFileExtention = '.js',
exportFileName = 'index.js',
} = cliArguments;
const svgFiles = readSvgDirectory(ICONS_DIR);
const icons = renderIconsObject(svgFiles, ICONS_DIR, cliArguments.renderUniqueKey);
const icons = renderIconsObject(svgFiles, ICONS_DIR, renderUniqueKey);
const defaultIconFileTemplate = './templates/defaultIconFileTemplate';
// eslint-disable-next-line import/no-dynamic-require
const iconFileTemplate = require(cliArguments.templateSrc || defaultIconFileTemplate).default;
const iconFileTemplate = require(templateSrc).default;
// Generates iconsNodes files for each icon
generateIconFiles(icons, OUTPUT_DIR, iconFileTemplate, { showLog: !cliArguments.silent });
generateIconFiles({
iconNodes: icons,
outputDirectory: OUTPUT_DIR,
template: iconFileTemplate,
showLog: !silent,
iconFileExtention,
});
// Generates entry files for the compiler filled with icons exports
generateExportsFile(path.join(SRC_DIR, 'icons/index.js'), path.join(OUTPUT_DIR, 'icons'), icons);
generateExportsFile(
path.join(OUTPUT_DIR, 'icons', exportFileName),
path.join(OUTPUT_DIR, 'icons'),
icons,
);