2025-11-30 22:44:47 +05:00
|
|
|
<!--
|
|
|
|
|
@component
|
|
|
|
|
|
|
|
|
|
Metro-like tile. Must be in a group to display correctly.
|
|
|
|
|
-->
|
|
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
|
import { cva } from "class-variance-authority";
|
|
|
|
|
|
2025-12-01 09:27:37 +05:00
|
|
|
/**
|
|
|
|
|
* Base size for a icon in pixels.
|
|
|
|
|
**/
|
2025-11-30 23:22:45 +05:00
|
|
|
const ICON_BASE_SIZE = 45;
|
|
|
|
|
|
2025-12-01 09:27:37 +05:00
|
|
|
/**
|
|
|
|
|
* Properties.
|
|
|
|
|
*/
|
2025-11-30 22:44:47 +05:00
|
|
|
let {
|
|
|
|
|
size,
|
|
|
|
|
row,
|
|
|
|
|
column,
|
2025-11-30 23:22:45 +05:00
|
|
|
children,
|
2025-11-30 22:44:47 +05:00
|
|
|
}: {
|
|
|
|
|
/**
|
|
|
|
|
* Size.
|
|
|
|
|
*/
|
|
|
|
|
size: "small" | "medium" | "wide" | "large";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Row index. Must be in a small tiles.
|
|
|
|
|
*/
|
|
|
|
|
row: number;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Column index. Must be in a small tiles.
|
|
|
|
|
*/
|
|
|
|
|
column: number;
|
|
|
|
|
|
|
|
|
|
/**
|
2025-11-30 23:22:45 +05:00
|
|
|
* Pages.
|
2025-11-30 22:44:47 +05:00
|
|
|
*/
|
2025-11-30 23:22:45 +05:00
|
|
|
children: () => any;
|
2025-11-30 22:44:47 +05:00
|
|
|
} = $props();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Tile style.
|
|
|
|
|
**/
|
2025-11-30 23:22:45 +05:00
|
|
|
const style = cva(["bg-(--tile-color)", "overflow-y-hidden"], {
|
2025-11-30 22:44:47 +05:00
|
|
|
variants: {
|
|
|
|
|
size: {
|
2025-12-01 08:43:37 +05:00
|
|
|
small: ["row-span-1", "col-span-1"],
|
|
|
|
|
medium: ["row-span-2", "col-span-2"],
|
2025-12-01 09:27:37 +05:00
|
|
|
wide: ["row-span-2", "col-span-4"],
|
2025-12-01 08:43:37 +05:00
|
|
|
large: ["row-span-4", "col-span-4"],
|
2025-11-30 22:44:47 +05:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
2025-11-30 23:22:45 +05:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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;
|
|
|
|
|
}
|
2025-11-30 22:44:47 +05:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
class={style({ size })}
|
|
|
|
|
style="
|
2025-11-30 23:22:45 +05:00
|
|
|
--tile-icon-size: {iconSize};
|
|
|
|
|
--tile-name-display: {size !== 'small' ? 'inline' : 'none'};
|
2025-11-30 22:44:47 +05:00
|
|
|
grid-row-start: {row};
|
2025-11-30 23:22:45 +05:00
|
|
|
grid-column-start: {column};
|
2025-11-30 22:44:47 +05:00
|
|
|
"
|
2025-11-30 23:22:45 +05:00
|
|
|
>
|
|
|
|
|
{@render children()}
|
|
|
|
|
</div>
|