2
0
mirror of https://github.com/iconify/iconify.git synced 2025-01-06 07:20:40 +00:00

Use TypeScript in Svelte component

This commit is contained in:
Vjacheslav Trushkin 2021-04-29 21:06:25 +03:00
parent eb2420177d
commit 292ba1b7cb
7 changed files with 344 additions and 22 deletions

View File

@ -1,20 +1,23 @@
{
"name": "@iconify/svelte",
"version": "1.0.3",
"version": "1.0.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@iconify/svelte",
"version": "1.0.3",
"version": "1.0.4",
"license": "MIT",
"devDependencies": {
"@iconify/core": "^1.0.0-rc.3",
"@rollup/plugin-commonjs": "^16.0.0",
"@rollup/plugin-node-resolve": "^10.0.0",
"@rollup/plugin-typescript": "^8.2.1",
"@tsconfig/svelte": "^1.0.10",
"rollup": "^2.33.3",
"rollup-plugin-svelte": "^6.1.1",
"svelte": "^3.29.7"
"svelte": "^3.29.7",
"svelte-preprocess": "^4.7.2"
}
},
"node_modules/@cyberalien/redundancy": {
@ -80,6 +83,24 @@
"rollup": "^1.20.0||^2.0.0"
}
},
"node_modules/@rollup/plugin-typescript": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.2.1.tgz",
"integrity": "sha512-Qd2E1pleDR4bwyFxqbjt4eJf+wB0UKVMLc7/BAFDGVdAXQMCsD4DUv5/7/ww47BZCYxWtJqe1Lo0KVNswBJlRw==",
"dev": true,
"dependencies": {
"@rollup/pluginutils": "^3.1.0",
"resolve": "^1.17.0"
},
"engines": {
"node": ">=8.0.0"
},
"peerDependencies": {
"rollup": "^2.14.0",
"tslib": "*",
"typescript": ">=3.7.0"
}
},
"node_modules/@rollup/pluginutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
@ -103,6 +124,12 @@
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
"dev": true
},
"node_modules/@tsconfig/svelte": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-1.0.10.tgz",
"integrity": "sha512-EBrpH2iXXfaf/9z81koiDYkp2mlwW2XzFcAqn6qh7VKyP8zBvHHAQzNhY+W9vH5arAjmGAm5g8ElWq6YmXm3ig==",
"dev": true
},
"node_modules/@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
@ -115,6 +142,12 @@
"integrity": "sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==",
"dev": true
},
"node_modules/@types/pug": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.4.tgz",
"integrity": "sha1-h3L80EGOPNLMFxVV1zAHQVBR9LI=",
"dev": true
},
"node_modules/@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@ -124,6 +157,15 @@
"@types/node": "*"
}
},
"node_modules/@types/sass": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.16.0.tgz",
"integrity": "sha512-2XZovu4NwcqmtZtsBR5XYLw18T8cBCnU2USFHTnYLLHz9fkhnoEMoDsqShJIOFsFhn5aJHjweiUUdTrDGujegA==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@ -170,6 +212,15 @@
"node": ">=0.10.0"
}
},
"node_modules/detect-indent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz",
"integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
@ -286,6 +337,15 @@
"sourcemap-codec": "^1.4.4"
}
},
"node_modules/min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@ -358,9 +418,6 @@
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.34.2.tgz",
"integrity": "sha512-mvtQLqu3cNeoctS+kZ09iOPxrc1P1/Bt1z15enuQ5feyKOdM3MJAVFjjsygurDpSWn530xB4AlA83TWIzRstXA==",
"dev": true,
"dependencies": {
"fsevents": "~2.1.2"
},
"bin": {
"rollup": "dist/bin/rollup"
},
@ -407,6 +464,18 @@
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"dev": true
},
"node_modules/strip-indent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
"dev": true,
"dependencies": {
"min-indent": "^1.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/svelte": {
"version": "3.31.0",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.31.0.tgz",
@ -416,6 +485,91 @@
"node": ">= 8"
}
},
"node_modules/svelte-preprocess": {
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.7.2.tgz",
"integrity": "sha512-EToG+08rEsA33btv+C5g2qnRArwpTc5AoU0QBB3ZEkYagxAb2yPNsy0qsmtvbJOTBMy6o3oyijDdl3DMpMvpEg==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
"@types/pug": "^2.0.4",
"@types/sass": "^1.16.0",
"detect-indent": "^6.0.0",
"strip-indent": "^3.0.0"
},
"engines": {
"node": ">= 9.11.2"
},
"peerDependencies": {
"@babel/core": "^7.10.2",
"coffeescript": "^2.5.1",
"less": "^3.11.3",
"postcss": "^7 || ^8",
"postcss-load-config": "^2.1.0 || ^3.0.0",
"pug": "^3.0.0",
"sass": "^1.26.8",
"stylus": "^0.54.7",
"sugarss": "^2.0.0",
"svelte": "^3.23.0",
"typescript": "^3.9.5 || ^4.0.0"
},
"peerDependenciesMeta": {
"@babel/core": {
"optional": true
},
"coffeescript": {
"optional": true
},
"less": {
"optional": true
},
"node-sass": {
"optional": true
},
"postcss": {
"optional": true
},
"postcss-load-config": {
"optional": true
},
"pug": {
"optional": true
},
"sass": {
"optional": true
},
"stylus": {
"optional": true
},
"sugarss": {
"optional": true
},
"typescript": {
"optional": true
}
}
},
"node_modules/tslib": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz",
"integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==",
"dev": true,
"peer": true
},
"node_modules/typescript": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
"integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
"dev": true,
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@ -475,6 +629,16 @@
"resolve": "^1.17.0"
}
},
"@rollup/plugin-typescript": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.2.1.tgz",
"integrity": "sha512-Qd2E1pleDR4bwyFxqbjt4eJf+wB0UKVMLc7/BAFDGVdAXQMCsD4DUv5/7/ww47BZCYxWtJqe1Lo0KVNswBJlRw==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.1.0",
"resolve": "^1.17.0"
}
},
"@rollup/pluginutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
@ -494,6 +658,12 @@
}
}
},
"@tsconfig/svelte": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-1.0.10.tgz",
"integrity": "sha512-EBrpH2iXXfaf/9z81koiDYkp2mlwW2XzFcAqn6qh7VKyP8zBvHHAQzNhY+W9vH5arAjmGAm5g8ElWq6YmXm3ig==",
"dev": true
},
"@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
@ -506,6 +676,12 @@
"integrity": "sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==",
"dev": true
},
"@types/pug": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.4.tgz",
"integrity": "sha1-h3L80EGOPNLMFxVV1zAHQVBR9LI=",
"dev": true
},
"@types/resolve": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@ -515,6 +691,15 @@
"@types/node": "*"
}
},
"@types/sass": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.16.0.tgz",
"integrity": "sha512-2XZovu4NwcqmtZtsBR5XYLw18T8cBCnU2USFHTnYLLHz9fkhnoEMoDsqShJIOFsFhn5aJHjweiUUdTrDGujegA==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@ -555,6 +740,12 @@
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
"dev": true
},
"detect-indent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz",
"integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==",
"dev": true
},
"estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
@ -652,6 +843,12 @@
"sourcemap-codec": "^1.4.4"
}
},
"min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
"dev": true
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@ -747,12 +944,47 @@
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
"dev": true
},
"strip-indent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
"dev": true,
"requires": {
"min-indent": "^1.0.0"
}
},
"svelte": {
"version": "3.31.0",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.31.0.tgz",
"integrity": "sha512-r+n8UJkDqoQm1b+3tA3Lh6mHXKpcfOSOuEuIo5gE2W9wQYi64RYX/qE6CZBDDsP/H4M+N426JwY7XGH4xASvGQ==",
"dev": true
},
"svelte-preprocess": {
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.7.2.tgz",
"integrity": "sha512-EToG+08rEsA33btv+C5g2qnRArwpTc5AoU0QBB3ZEkYagxAb2yPNsy0qsmtvbJOTBMy6o3oyijDdl3DMpMvpEg==",
"dev": true,
"requires": {
"@types/pug": "^2.0.4",
"@types/sass": "^1.16.0",
"detect-indent": "^6.0.0",
"strip-indent": "^3.0.0"
}
},
"tslib": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz",
"integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==",
"dev": true,
"peer": true
},
"typescript": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
"integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==",
"dev": true,
"peer": true
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",

View File

@ -22,8 +22,11 @@
"@iconify/core": "^1.0.0-rc.3",
"@rollup/plugin-commonjs": "^16.0.0",
"@rollup/plugin-node-resolve": "^10.0.0",
"@rollup/plugin-typescript": "^8.2.1",
"@tsconfig/svelte": "^1.0.10",
"rollup": "^2.33.3",
"rollup-plugin-svelte": "^6.1.1",
"svelte": "^3.29.7"
"svelte": "^3.29.7",
"svelte-preprocess": "^4.7.2"
}
}

View File

@ -2,6 +2,8 @@ import fs from 'fs';
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import sveltePreprocess from 'svelte-preprocess';
import pkg from './package.json';
// Copy Icon.svelte
@ -18,7 +20,7 @@ try {
// Create component.mjs
fs.writeFileSync(
__dirname + '/dist/component.mjs',
fs.readFileSync(__dirname + '/src/index.js')
fs.readFileSync(__dirname + '/src/index.ts')
);
// Create bundle
@ -30,22 +32,37 @@ const name = pkg.name
export default [
// Bundle everything
{
input: 'src/index.js',
input: 'src/index.ts',
output: [
{ file: pkg.module, format: 'es' },
{ file: pkg.main, format: 'umd', name },
],
plugins: [svelte(), resolve(), commonjs()],
plugins: [
svelte({
preprocess: sveltePreprocess(),
}),
resolve({
extensions: ['.ts', '.js', '.svelte'],
}),
typescript(),
commonjs(),
],
},
// Files included in Icon.svelte as bundles without dependencies
{
input: 'src/generate-icon.js',
input: 'src/generate-icon.ts',
output: [
{
file: 'dist/generate-icon.js',
format: 'es',
},
],
plugins: [resolve(), commonjs()],
plugins: [
resolve({
extensions: ['.ts', '.js', '.svelte'],
}),
typescript(),
commonjs(),
],
},
];

View File

@ -8,6 +8,7 @@ import { fullIcon } from '@iconify/core/lib/icon';
import { iconToSVG } from '@iconify/core/lib/builder';
import { replaceIDs } from '@iconify/core/lib/builder/ids';
import { merge } from '@iconify/core/lib/misc/merge';
import type { IconProps } from './props';
/**
* Default SVG attributes
@ -19,10 +20,18 @@ const svgDefaults = {
'role': 'img',
};
/**
* Result
*/
export interface GenerateIconResult {
attributes: Record<string, unknown>;
body: string;
}
/**
* Generate icon from properties
*/
export function generateIcon(props) {
export function generateIcon(props: IconProps): GenerateIconResult {
let iconData = fullIcon(props.icon);
if (!iconData) {
return {
@ -31,15 +40,15 @@ export function generateIcon(props) {
};
}
const customisations = merge(defaults, props);
const componentProps = merge(svgDefaults);
const customisations = merge(defaults, props as typeof defaults);
const componentProps = merge(svgDefaults) as Record<string, unknown>;
// Create style if missing
let style = typeof props.style === 'string' ? props.style : '';
// Get element properties
for (let key in props) {
const value = props[key];
const value = props[key as keyof typeof props] as unknown;
switch (key) {
// Properties to ignore
case 'icon':
@ -48,12 +57,16 @@ export function generateIcon(props) {
// Flip as string: 'horizontal,vertical'
case 'flip':
flipFromString(customisations, value);
if (typeof value === 'string') {
flipFromString(customisations, value);
}
break;
// Alignment as string
case 'align':
alignmentFromString(customisations, value);
if (typeof value === 'string') {
alignmentFromString(customisations, value);
}
break;
// Color: copy to style
@ -63,9 +76,9 @@ export function generateIcon(props) {
// Rotation as string
case 'rotate':
if (typeof value !== 'number') {
if (typeof value === 'string') {
customisations[key] = rotateFromString(value);
} else {
} else if (typeof value === 'number') {
componentProps[key] = value;
}
break;
@ -80,7 +93,7 @@ export function generateIcon(props) {
// Copy missing property if it does not exist in customisations
default:
if (defaults[key] === void 0) {
if ((defaults as Record<string, unknown>)[key] === void 0) {
componentProps[key] = value;
}
}
@ -91,7 +104,8 @@ export function generateIcon(props) {
// Add icon stuff
for (let key in item.attributes) {
componentProps[key] = item.attributes[key];
componentProps[key] =
item.attributes[key as keyof typeof item.attributes];
}
if (item.inline) {

View File

@ -0,0 +1,40 @@
import type { IconifyIcon } from '@iconify/types';
import type { IconifyIconCustomisations as IconCustomisations } from '@iconify/core/lib/customisations';
// Allow rotation to be string
/**
* Icon customisations
*/
export type IconifyIconCustomisations = IconCustomisations & {
rotate?: string | number;
};
/**
* Icon properties
*/
export interface IconifyIconProps extends IconifyIconCustomisations {
// Icon object
icon: IconifyIcon;
// Style
color?: string;
// Shorthand properties
flip?: string;
align?: string;
// Unique id, used as base for ids for shapes. Use it to get consistent ids for server side rendering
id?: string;
}
/**
* Properties for element that are mentioned in generate-icon.ts
*/
interface IconifyElementProps {
style?: string;
}
/**
* Mix of icon properties and HTMLElement properties
*/
export type IconProps = IconifyElementProps & IconifyIconProps;

View File

@ -0,0 +1,16 @@
{
"compilerOptions": {
"rootDir": "src",
"target": "es2017",
"module": "esnext",
"declaration": false,
"sourceMap": false,
"strict": true,
"types": ["node", "svelte"],
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"importsNotUsedAsValues": "error"
}
}