refactor(components/tiles): icon/name page as a seperate component

This commit is contained in:
mikhail "synzr" 2025-11-30 23:22:45 +05:00
parent 11f3c05d8f
commit 144b43edd4
3 changed files with 82 additions and 11 deletions

View file

@ -7,11 +7,14 @@ Metro-like tile. Must be in a group to display correctly.
<script lang="ts">
import { cva } from "class-variance-authority";
// Base size for a icon in pixels.
const ICON_BASE_SIZE = 45;
let {
size,
row,
column,
icon,
children,
}: {
/**
* Size.
@ -29,15 +32,15 @@ Metro-like tile. Must be in a group to display correctly.
column: number;
/**
* Icon.
* Pages.
*/
icon: string;
children: () => any;
} = $props();
/**
* Tile style.
**/
const style = cva(["bg-(--tile-color)", "bg-center", "bg-no-repeat"], {
const style = cva(["bg-(--tile-color)", "overflow-y-hidden"], {
variants: {
size: {
small: "bg-size-[45px]",
@ -47,13 +50,33 @@ Metro-like tile. Must be in a group to display correctly.
},
},
});
/**
* Icon size. Based on tile's size.
*/
let iconSize: string = $state("0");
switch (size) {
case "small":
iconSize = `${ICON_BASE_SIZE}px`;
break;
case "medium":
case "wide":
iconSize = `${ICON_BASE_SIZE * 2}px`;
break;
case "large":
iconSize = `${ICON_BASE_SIZE * 4}px`;
break;
}
</script>
<div
class={style({ size })}
style="
background-image: url({icon});
grid-column-start: {column};
--tile-icon-size: {iconSize};
--tile-name-display: {size !== 'small' ? 'inline' : 'none'};
grid-row-start: {row};
grid-column-start: {column};
"
></div>
>
{@render children()}
</div>

View file

@ -0,0 +1,39 @@
<!--
@component
Icon page for a tile. Must be in a tile to display correctly.
-->
<script lang="ts">
let {
icon,
name,
}: {
/**
* Icon. Must be a valid image URL.
*/
icon: string;
/**
* Name.
*/
name?: string;
} = $props();
</script>
<div
class="h-full flex flex-col justify-end bg-center bg-no-repeat"
style="
background-image: url('{icon}');
background-size: var(--tile-icon-size);
"
>
{#if name}
<h1
class="w-full p-2 text-white select-none"
style="display: var(--tile-name-display);"
>
{name}
</h1>
{/if}
</div>