Improved icon rendering

This commit is contained in:
Jordan Roher 2023-04-21 14:40:19 -07:00
parent adf1302364
commit af3d479648
2 changed files with 85 additions and 52 deletions

View File

@ -18,6 +18,21 @@ Inspired by [Ben Phelps' Homepage](https://gethomepage.dev/) and [Umbrel](https:
# Icons # Icons
## Options
- Set a background by providing an "iconBG" from the [list of Tailwind colors](https://tailwindcss.com/docs/background-color). Do not prefix with "bg-".
- Turn off the bubble and shadow by setting `"iconBubble": false`.
- Turn off background color by setting `"iconBG": "transparent"`.
- Hide the icon entirely by setting `"icon": ""`.
```bash
# Specify an icon in config.json
"icon": "/icons/jellyfin.jpg",
"iconColor": "blue-500", # optional, defaults to a contrasting color
"iconBG": "gray-200", # optional, defaults to a complementary color
"iconBubble": false, # optional, defaults to true
```
## Use your own ## Use your own
Create a volume or bind mount to a subfolder of `/app/public` and specify a relative path. Create a volume or bind mount to a subfolder of `/app/public` and specify a relative path.
@ -51,20 +66,9 @@ Use any [Material Design icon](https://icon-sets.iconify.design/mdi/) by prefixi
Fill the icon by providing an "iconColor" from the [list of Tailwind colors](https://tailwindcss.com/docs/background-color). Do not prefix with "bg-". Fill the icon by providing an "iconColor" from the [list of Tailwind colors](https://tailwindcss.com/docs/background-color). Do not prefix with "bg-".
Set a background by providing an "iconBG" from the [list of Tailwind colors](https://tailwindcss.com/docs/background-color). Do not prefix with "bg-".
Turn off the bubble and shadow by setting `"iconBubble": false`.
Turn off background color by setting `"iconBG": "transparent"`.
Hide the icon entirely by setting `"icon": ""`.
```bash ```bash
# Specify an icon in config.json # Specify an icon in config.json
"icon": "mdi-cloud", "icon": "mdi-cloud"
"iconColor": "blue-500", # optional, defaults to a contrasting color
"iconBG": "gray-200", # optional, defaults to a complementary color
"iconBubble": false, # optional, defaults to true
``` ```
# Docker compose # Docker compose

View File

@ -70,6 +70,12 @@ const IconBlank: React.FunctionComponent<IIconBlankProps> = ({ index }) => {
); );
}; };
enum IconType {
uri,
material,
dashboard,
}
interface IIconBaseProps { interface IIconBaseProps {
icon: string; icon: string;
iconColor?: string; iconColor?: string;
@ -78,51 +84,74 @@ interface IIconBaseProps {
} }
const IconBase: React.FunctionComponent<IIconBaseProps> = ({ icon, iconBG, iconBubble, iconColor }) => { const IconBase: React.FunctionComponent<IIconBaseProps> = ({ icon, iconBG, iconBubble, iconColor }) => {
let iconType: IconType = IconType.uri;
if (icon.startsWith("http") || icon.startsWith("/")) { if (icon.startsWith("http") || icon.startsWith("/")) {
/* Relative or absolute icon URI */ iconType = IconType.uri;
return ( } else if (icon.startsWith("mdi-")) {
<img iconType = IconType.material;
src={icon} } else {
alt="" iconType = IconType.dashboard;
className=" block w-16 h-16 rounded-2xl border border-black/5 shadow-sm overflow-hidden"
/>
);
} }
if (icon.startsWith("mdi-")) { // Everyone starts the same size
/* Material Design icon */ let iconClassName = "block w-16 h-16 overflow-hidden bg-contain";
const iconName = icon.replace("mdi-", "").replace(".svg", "");
let iconClassName =
iconBubble === false
? "block w-16 h-16 overflow-hidden"
: "block w-16 h-16 rounded-2xl border border-black/5 shadow-sm overflow-hidden";
if (is.null(iconBG)) { if (is.null(iconBubble) || iconBubble !== false) {
iconClassName += ` bg-slate-200`; iconClassName += " rounded-2xl border border-black/5 shadow-sm";
} else { }
iconClassName += ` bg-${iconBG}`;
}
return ( switch (iconType) {
<div className={iconClassName}> case IconType.uri:
<div case IconType.dashboard:
className={`block w-16 h-16 bg-${iconColor} overflow-hidden`} // Default to bubble and no background for URI and Dashboard icons
style={{ if (!is.null(iconBG)) {
mask: `url(https://cdn.jsdelivr.net/npm/@mdi/svg@latest/svg/${iconName}.svg) no-repeat center / contain`, iconClassName += ` bg-${iconBG}`;
WebkitMask: `url(https://cdn.jsdelivr.net/npm/@mdi/svg@latest/svg/${iconName}.svg) no-repeat center / contain`, }
}} break;
case IconType.material:
// Material icons get a color and a background by default, then an optional bubble
if (is.null(iconBG)) {
iconClassName += ` bg-slate-200`;
} else {
iconClassName += ` bg-${iconBG}`;
}
if (is.null(iconBubble) || iconBubble !== false) {
iconClassName += " rounded-2xl border border-black/5 shadow-sm";
}
if (is.null(iconColor)) {
iconColor = "black";
}
break;
}
switch (iconType) {
case IconType.uri:
return <img src={icon} alt="" className={iconClassName} />;
case IconType.dashboard:
icon = icon.replace(".png", "").replace(".jpg", "").replace(".svg", "");
return (
<img
src={`https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${icon}.png`}
alt=""
className={iconClassName}
/> />
</div> );
); case IconType.material:
} icon = icon.replace("mdi-", "").replace(".svg", "");
/* Dashboard icon */ return (
const iconName = icon.replace(".png", "").replace(".jpg", "").replace(".svg", ""); <div className={iconClassName}>
return ( <div
<img className={`block w-16 h-16 bg-${iconColor} overflow-hidden`}
src={`https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${iconName}.png`} style={{
alt="" mask: `url(https://cdn.jsdelivr.net/npm/@mdi/svg@latest/svg/${icon}.svg) no-repeat center / contain`,
className="block w-16 h-16 rounded-2xl border border-black/5 shadow-sm overflow-hidden" WebkitMask: `url(https://cdn.jsdelivr.net/npm/@mdi/svg@latest/svg/${icon}.svg) no-repeat center / contain`,
/> }}
); />
</div>
);
}
}; };