Skip to content

Commit

Permalink
Refactor icon naming and add error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
nuxodin committed Feb 8, 2024
1 parent f1b90c2 commit 49070a9
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 95 deletions.
33 changes: 19 additions & 14 deletions ico.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// icons from directory
// [u1-ico] {
// --directory:'https://cdn.jsdelivr.net/npm/[email protected]/outline/';
// --u1-ico-dir:'https://cdn.jsdelivr.net/npm/[email protected]/outline/x-{icon-name}.svg';
// }

const uIco = class extends HTMLElement {
Expand All @@ -20,34 +20,39 @@ const uIco = class extends HTMLElement {
const name = this.getAttribute('icon') || inner;
this.setAttribute('icon',name);

let [prefix, firstWord, between='', nextWord, suffix='.svg'] = dir.split(/{(icon)([^n]*)?(name)?}/i);
let [prefix, firstWord, between='', nextWord, suffix] = dir.split(/{(icon)([^n]*)?(name)?}/i);
if (!suffix) suffix = '.svg';
if (!nextWord) between = '-'; // if just: {icon}

// icon nameing convertion
// icon naming convertion
let fileName = name;
const upperFirst = firstWord && firstWord[0] === 'I';
const upperWords = nextWord && nextWord[0] === 'N';
const upperFirst = firstWord?.[0] === 'I';
const upperWords = nextWord?.[0] === 'N';
if (upperFirst) fileName = fileName.replace(/^([a-z])/, g => g[0].toUpperCase()); // first upper
if (upperWords) fileName = fileName.replace(/-([a-z])/g, g => g[1].toUpperCase()); // camel-case
if (between !== '-') fileName = fileName.replace(/-/g, between);

const path = prefix + fileName + suffix;

this.setAttribute('state','loading');
var svg = fetch(path, {cache: "force-cache"}).then(res=>{ // "force-cache": why is the response not cached like direct in the browser?
if (!res.ok) throw new Error("Not 2xx response (does the icon not exist?)");
res.text().then(svg=>{
fetch(path, {cache: "force-cache"}) // "force-cache": why is the response not cached like direct in the browser?
.then(res=>{
if (!res.ok) throw new Error("Not 2xx response (does the icon not exist?)");
return res.text();
})
.then(svg=>{
this.setAttribute('state','ok');
this.innerHTML = svg;

if (inner) { // if the name was the content of the element, it was indened as a label
if (inner) { // if the name was the content of the element, it was intended to be the label
this.firstElementChild.setAttribute('aria-label', inner);
} else {
this.firstElementChild.setAttribute('aria-hidden', 'true');
}
})
.catch(err=>{
this.setAttribute('state','fail');
// todo retry? console.warn('failed to load "' + fileName + '" in ' + prefix);
});
}).catch(err=>{
this.setAttribute('state','fail');
// todo retry? console.warn('failed to load "' + fileName + '" in ' + prefix);
});
}
}
}
Expand Down
114 changes: 114 additions & 0 deletions tests/fonts.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<!--script src="../../u1/tests/test-init.js" type=module></script-->
<title>u1-ico Test</title>

<link rel=stylesheet href="https://cdn.jsdelivr.net/gh/u1ui/norm.css/norm.min.css">
<link rel=stylesheet href="https://cdn.jsdelivr.net/gh/u1ui/base.css/base.min.css">
<link rel=stylesheet href="https://cdn.jsdelivr.net/gh/u1ui/classless.css/variables.min.css">
<link rel=stylesheet href="https://cdn.jsdelivr.net/gh/u1ui/classless.css/classless.min.css">
<link rel=stylesheet href="https://cdn.jsdelivr.net/gh/u1ui/classless.css/simple.min.css">
<link rel=stylesheet href="https://cdn.jsdelivr.net/gh/u1ui/classless.css/more.min.css">

<link rel="stylesheet" href="./util.css">
<script type=module src="./util.js"></script>

<link rel="stylesheet" href="../font/Material Icons.css">
<link rel="stylesheet" href="../font/LigatureSymbols.css">
<link rel="stylesheet" href="../font/RemixFilled.css">
<link rel="stylesheet" href="../font/RemixOutlined.css">
<link rel="stylesheet" href="../font/Font Awesome.css">


<link rel="stylesheet" href="../ico.css">
<script type=module src="../ico.js"></script>

<body>

<h2>Font Awesome</h2>
<div style="display:flex; flex-wrap:wrap; gap:.2rem;" id=lsView>
<script>
for (let icon of '🧭︁,📞︁,+︁,👤︁,︁,'.split(',')) {
document.write('<div style="text-align:center"><u1-ico style="--u1-ico-font:\'Font Awesome\';">'+icon+'</u1-ico><div style="font-size:12px">'+icon+'</div></div>');
}
</script>
<script>
for (let icon of '︁,︁,︁,︁'.split(',')) {
document.write('<div style="text-align:center"><u1-ico style="--u1-ico-font:\'Font Awesome\';">'+icon+'</u1-ico><div style="font-size:12px">'+icon+'</div></div>');
}
</script>

</div>


<h2>LigatureSymbols</h2>
<div style="--u1-ico-font:'LigatureSymbols'">
<div style="display:flex; flex-wrap:wrap; gap:.2rem" id=lsView>
<script type=module>
ligaturesFromFamily('LigatureSymbols').then(function(ligas){
var str = '';
for (let icon of Object.keys(ligas)) {
str += '<div style="text-align:center"><u1-ico>'+icon+'</u1-ico><div style="font-size:18px">'+icon+'</div></div>';
}
lsView.innerHTML = str;
});
</script>
<script>
for (let icon of 'twitter,youtube,copy,not_found'.split(',')) {
document.write('<div style="text-align:center"><u1-ico>'+icon+'</u1-ico><div style="font-size:12px">'+icon+'</div></div>');
}
</script>
</div>
</div>

<h2>Material Icons</h2>
<div style="--u1-ico-font:'Material Icons'">
<!--select onchange="this.parentNode.style.setProperty('--u1-ico-font',this.value)">
<option value="Material Icons">--u1-ico-font:'Material Icons'</option>
<option value="Material Icons Outlined">--u1-ico-font:'Material Icons Outlined'</option>
<option value="Material Icons Round">--u1-ico-font:'Material Icons Round'</option>
<option value="Material Icons Sharp">--u1-ico-font:'Material Icons Sharp'</option>
<option value="Material Icons Two Tone">--u1-ico-font:'Material Icons Two Tone'</option>
</select><br-->
<div style="display:flex; flex-wrap:wrap; gap:.2rem" id=materialView>
<script type=module>
/*
ligaturesFromFamily('Material Icons').then(function(ligas){
var str = '';
for (let icon of Object.keys(ligas)) {
str += '<u1-ico title="'+icon+'">'+icon+'</u1-ico>';
}
materialView.innerHTML = str;
});
*/
</script>
<script>
for (let icon of 'star,add,clear,call,snowboarding,not_found'.split(',')) {
document.write('<div style="text-align:center"><u1-ico>'+icon+'</u1-ico><div style="font-size:12px">'+icon+'</div></div>');
}
</script>
</div>
</div>

<h2>Remixicon Font</h2>
<div style="--u1-ico-font:'RemixOutlined'">
<div style="display:flex; flex-wrap:wrap; gap:.2rem" id=remixView>
<script type=module>
ligaturesFromFamily('RemixOutlined').then(function(ligas){
var str = '';
for (let icon of Object.keys(ligas)) {
str += '<u1-ico title="'+icon+'">'+icon+'</u1-ico>';
}
remixView.innerHTML = str;
});
</script>
<script>
for (let icon of 'star,heart,home,file,key,sun,not_found'.split(',')) {
document.write('<div style="text-align:center"><u1-ico>'+icon+'</u1-ico><div style="font-size:12px">'+icon+'</div></div>');
}
</script>
</div>
</div>
114 changes: 33 additions & 81 deletions tests/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
}
</style>


<h2>Variants</h2>
<div>
<table>
Expand Down Expand Up @@ -110,92 +109,45 @@ <h2>Variants</h2>
</div>


<h2>Font Awesome</h2>
<div style="display:flex; flex-wrap:wrap; gap:.2rem;" id=lsView>
<script>
for (let icon of '🧭︁,📞︁,+︁,👤︁,︁,'.split(',')) {
document.write('<div style="text-align:center"><u1-ico style="--u1-ico-font:\'Font Awesome\';">'+icon+'</u1-ico><div style="font-size:12px">'+icon+'</div></div>');
}
</script>
<script>
for (let icon of '︁,︁,︁,︁'.split(',')) {
document.write('<div style="text-align:center"><u1-ico style="--u1-ico-font:\'Font Awesome\';">'+icon+'</u1-ico><div style="font-size:12px">'+icon+'</div></div>');
}
</script>

</div>


<h2>LigatureSymbols</h2>
<div style="--u1-ico-font:'LigatureSymbols'">
<div style="display:flex; flex-wrap:wrap; gap:.2rem" id=lsView>
<script type=module>
ligaturesFromFamily('LigatureSymbols').then(function(ligas){
var str = '';
for (let icon of Object.keys(ligas)) {
str += '<div style="text-align:center"><u1-ico>'+icon+'</u1-ico><div style="font-size:18px">'+icon+'</div></div>';
}
lsView.innerHTML = str;
});
</script>
<script>
for (let icon of 'twitter,youtube,copy,not_found'.split(',')) {
document.write('<div style="text-align:center"><u1-ico>'+icon+'</u1-ico><div style="font-size:12px">'+icon+'</div></div>');
}
</script>
<h2>Tests</h2>
<div id="variants">

<div>
--u1-ico-dir, innerHTML
<u1-ico style="--u1-ico-dir:'https://cdn.jsdelivr.net/npm/@material-icons/[email protected]/svg/{icon}/baseline.svg'" >
search
</u1-ico>
</div>
<div>
--u1-ico-dir, icon-attribute, {icon}
<u1-ico icon=search style="--u1-ico-dir:'https://cdn.jsdelivr.net/npm/@material-icons/[email protected]/svg/{icon}/baseline.svg'"></u1-ico>
</div>
</div>

<h2>Material Icons</h2>
<div style="--u1-ico-font:'Material Icons'">
<!--select onchange="this.parentNode.style.setProperty('--u1-ico-font',this.value)">
<option value="Material Icons">--u1-ico-font:'Material Icons'</option>
<option value="Material Icons Outlined">--u1-ico-font:'Material Icons Outlined'</option>
<option value="Material Icons Round">--u1-ico-font:'Material Icons Round'</option>
<option value="Material Icons Sharp">--u1-ico-font:'Material Icons Sharp'</option>
<option value="Material Icons Two Tone">--u1-ico-font:'Material Icons Two Tone'</option>
</select><br-->
<div style="display:flex; flex-wrap:wrap; gap:.2rem" id=materialView>
<script type=module>
/*
ligaturesFromFamily('Material Icons').then(function(ligas){
var str = '';
for (let icon of Object.keys(ligas)) {
str += '<u1-ico title="'+icon+'">'+icon+'</u1-ico>';
}
materialView.innerHTML = str;
});
*/
</script>
<script>
for (let icon of 'star,add,clear,call,snowboarding,not_found'.split(',')) {
document.write('<div style="text-align:center"><u1-ico>'+icon+'</u1-ico><div style="font-size:12px">'+icon+'</div></div>');
}
</script>
<div>
--u1-ico-dir, icon-attribute, {icon_name}
<u1-ico icon=chevron-right style="--u1-ico-dir:'https://cdn.jsdelivr.net/npm/@material-icons/[email protected]/svg/{icon_name}/baseline.svg'"></u1-ico>
</div>
<div>
--u1-ico-dir, icon-attribute, {icon} without ".svg" suffix
<u1-ico icon="search/baseline" style="--u1-ico-dir:'https://cdn.jsdelivr.net/npm/@material-icons/[email protected]/svg/{icon}'"></u1-ico>
</div>
</div>

<h2>Remixicon Font</h2>
<div style="--u1-ico-font:'RemixOutlined'">
<div style="display:flex; flex-wrap:wrap; gap:.2rem" id=remixView>
<script type=module>
ligaturesFromFamily('RemixOutlined').then(function(ligas){
var str = '';
for (let icon of Object.keys(ligas)) {
str += '<u1-ico title="'+icon+'">'+icon+'</u1-ico>';
}
remixView.innerHTML = str;
});
</script>
<script>
for (let icon of 'star,heart,home,file,key,sun,not_found'.split(',')) {
document.write('<div style="text-align:center"><u1-ico>'+icon+'</u1-ico><div style="font-size:12px">'+icon+'</div></div>');
}
</script>
<div>
direct svg
<u1-ico>
<svg width="24" height="24" viewBox="0 0 24 24"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"></path></svg>
</u1-ico>
</div>
<div>
--u1-ico-dir, innerHTML
<u1-ico style="--u1-ico-font:Material Icons">
search
</u1-ico>
</div>

</div>




<h2>Vertical alignement</h2>
<div style="--u1-ico-font:'Material Icons'">
<h3>Using [inline]</h3>
Expand Down

0 comments on commit 49070a9

Please sign in to comment.