2
0
mirror of https://github.com/iconify/iconify.git synced 2025-01-12 01:45:41 +00:00

Fix import of uncompiled Svelte component by splitting dependencies into a separate file and bundle that file

This commit is contained in:
Vjacheslav Trushkin 2020-08-22 15:31:44 +03:00
parent 664173e8a6
commit 5c87d82108
4 changed files with 151 additions and 123 deletions

View File

@ -2,7 +2,7 @@
"name": "@iconify/svelte",
"description": "Iconify icon component for Svelte.",
"author": "Vjacheslav Trushkin",
"version": "1.0.1",
"version": "1.0.2",
"license": "MIT",
"bugs": "https://github.com/iconify/iconify/issues",
"homepage": "https://github.com/iconify/iconify",
@ -11,7 +11,7 @@
"url": "https://github.com/iconify/iconify.git",
"directory": "packages/svelte"
},
"svelte": "src/index.js",
"svelte": "dist/Icon.svelte",
"module": "dist/index.mjs",
"main": "dist/index.js",
"scripts": {

View File

@ -1,18 +1,45 @@
import fs from 'fs';
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import pkg from './package.json';
// Copy Icon.svelte
try {
fs.mkdirSync(__dirname + '/dist');
} catch (err) {}
['Icon.svelte'].forEach((file) => {
fs.writeFileSync(
__dirname + '/dist/' + file,
fs.readFileSync(__dirname + '/src/' + file)
);
});
// Create bundle
const name = pkg.name
.replace(/^(@\S+\/)?(svelte-)?(\S+)/, '$3')
.replace(/^\w/, (m) => m.toUpperCase())
.replace(/-\w/g, (m) => m[1].toUpperCase());
export default {
input: 'src/index.js',
output: [
{ file: pkg.module, format: 'es' },
{ file: pkg.main, format: 'umd', name },
],
plugins: [svelte(), resolve(), commonjs()],
};
export default [
// Bundle everything
{
input: 'src/index.js',
output: [
{ file: pkg.module, format: 'es' },
{ file: pkg.main, format: 'umd', name },
],
plugins: [svelte(), resolve(), commonjs()],
},
// Files included in Icon.svelte as bundles without dependencies
{
input: 'src/generate-icon.js',
output: [
{
file: 'dist/generate-icon.js',
format: 'es',
},
],
plugins: [resolve(), commonjs()],
},
];

View File

@ -1,120 +1,9 @@
<script context="module">
import { defaults } from '@iconify/core/lib/customisations';
import {
flipFromString,
alignmentFromString,
} from '@iconify/core/lib/customisations/shorthand';
import { rotateFromString } from '@iconify/core/lib/customisations/rotate';
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';
/**
* Default SVG attributes
*/
const svgDefaults = {
'xmlns': 'http://www.w3.org/2000/svg',
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
'aria-hidden': true,
'focusable': false,
'role': 'img',
};
</script>
<script>
import { generateIcon } from './generate-icon';
// Generated data
let data;
// Generate icon
function generateIcon(props) {
let iconData = fullIcon(props.icon);
if (!iconData) {
return {
attributes: svgDefaults,
body: '',
};
}
const customisations = merge(defaults, props);
const componentProps = merge(svgDefaults);
// Create style if missing
let style = typeof props.style === 'string' ? props.style : '';
// Get element properties
for (let key in props) {
const value = props[key];
switch (key) {
// Properties to ignore
case 'icon':
case 'style':
break;
// Flip as string: 'horizontal,vertical'
case 'flip':
flipFromString(customisations, value);
break;
// Alignment as string
case 'align':
alignmentFromString(customisations, value);
break;
// Color: copy to style
case 'color':
style = 'color: ' + value + '; ' + style;
break;
// Rotation as string
case 'rotate':
if (typeof value !== 'number') {
customisations[key] = rotateFromString(value);
} else {
componentProps[key] = value;
}
break;
// Remove aria-hidden
case 'ariaHidden':
case 'aria-hidden':
if (value !== true && value !== 'true') {
delete componentProps['aria-hidden'];
}
break;
// Copy missing property if it does not exist in customisations
default:
if (defaults[key] === void 0) {
componentProps[key] = value;
}
}
}
// Generate icon
const item = iconToSVG(iconData, customisations);
// Add icon stuff
for (let key in item.attributes) {
componentProps[key] = item.attributes[key];
}
if (item.inline) {
style = 'vertical-align: -0.125em; ' + style;
}
// Style
if (style !== '') {
componentProps.style = style;
}
// Generate HTML
return {
attributes: componentProps,
body: replaceIDs(item.body),
};
}
$: {
data = generateIcon($$props);
}

View File

@ -0,0 +1,112 @@
import { defaults } from '@iconify/core/lib/customisations';
import {
flipFromString,
alignmentFromString,
} from '@iconify/core/lib/customisations/shorthand';
import { rotateFromString } from '@iconify/core/lib/customisations/rotate';
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';
/**
* Default SVG attributes
*/
const svgDefaults = {
'xmlns': 'http://www.w3.org/2000/svg',
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
'aria-hidden': true,
'focusable': false,
'role': 'img',
};
/**
* Generate icon from properties
*/
export function generateIcon(props) {
let iconData = fullIcon(props.icon);
if (!iconData) {
return {
attributes: svgDefaults,
body: '',
};
}
const customisations = merge(defaults, props);
const componentProps = merge(svgDefaults);
// Create style if missing
let style = typeof props.style === 'string' ? props.style : '';
// Get element properties
for (let key in props) {
const value = props[key];
switch (key) {
// Properties to ignore
case 'icon':
case 'style':
break;
// Flip as string: 'horizontal,vertical'
case 'flip':
flipFromString(customisations, value);
break;
// Alignment as string
case 'align':
alignmentFromString(customisations, value);
break;
// Color: copy to style
case 'color':
style = 'color: ' + value + '; ' + style;
break;
// Rotation as string
case 'rotate':
if (typeof value !== 'number') {
customisations[key] = rotateFromString(value);
} else {
componentProps[key] = value;
}
break;
// Remove aria-hidden
case 'ariaHidden':
case 'aria-hidden':
if (value !== true && value !== 'true') {
delete componentProps['aria-hidden'];
}
break;
// Copy missing property if it does not exist in customisations
default:
if (defaults[key] === void 0) {
componentProps[key] = value;
}
}
}
// Generate icon
const item = iconToSVG(iconData, customisations);
// Add icon stuff
for (let key in item.attributes) {
componentProps[key] = item.attributes[key];
}
if (item.inline) {
style = 'vertical-align: -0.125em; ' + style;
}
// Style
if (style !== '') {
componentProps.style = style;
}
// Generate HTML
return {
attributes: componentProps,
body: replaceIDs(item.body),
};
}