feat(components/tiles): basic tiles

This commit is contained in:
mikhail "synzr" 2025-11-30 22:44:47 +05:00
parent 7eccdb617b
commit 11f3c05d8f
9 changed files with 153 additions and 2 deletions

View file

@ -2,5 +2,9 @@
"files.associations": {
"*.css": "tailwindcss"
},
"editor.formatOnSave": true
"editor.formatOnSave": true,
"tailwindCSS.classFunctions": [
"cva",
"cx"
]
}

View file

@ -22,6 +22,7 @@
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"@tailwindcss/vite": "^4.1.17",
"@types/node": "^22",
"class-variance-authority": "^0.7.1",
"eslint": "^9.39.1",
"eslint-plugin-svelte": "^3.13.0",
"globals": "^16.5.0",

10
pnpm-lock.yaml generated
View file

@ -35,6 +35,9 @@ importers:
'@types/node':
specifier: ^22
version: 22.19.1
class-variance-authority:
specifier: ^0.7.1
version: 0.7.1
eslint:
specifier: ^9.39.1
version: 9.39.1(jiti@2.6.1)
@ -673,6 +676,9 @@ packages:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'}
class-variance-authority@0.7.1:
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
clsx@2.1.1:
resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'}
@ -1791,6 +1797,10 @@ snapshots:
dependencies:
readdirp: 4.1.2
class-variance-authority@0.7.1:
dependencies:
clsx: 2.1.1
clsx@2.1.1: {}
color-convert@2.0.1:

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View file

@ -0,0 +1,59 @@
<!--
@component
Metro-like tile. Must be in a group to display correctly.
-->
<script lang="ts">
import { cva } from "class-variance-authority";
let {
size,
row,
column,
icon,
}: {
/**
* 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;
/**
* Icon.
*/
icon: string;
} = $props();
/**
* Tile style.
**/
const style = cva(["bg-(--tile-color)", "bg-center", "bg-no-repeat"], {
variants: {
size: {
small: "bg-size-[45px]",
medium: ["col-span-2", "row-span-2", "bg-size-[90px]"],
wide: ["col-span-4", "row-span-2", "bg-size-[90px]"],
large: ["col-span-4", "row-span-4", "bg-size-[180px]"],
},
},
});
</script>
<div
class={style({ size })}
style="
background-image: url({icon});
grid-column-start: {column};
grid-row-start: {row};
"
></div>

View file

@ -0,0 +1,63 @@
<!--
@component
A group of tiles. Places them correctly in a grid.
-->
<script lang="ts">
let {
title,
rows,
columns,
color = "var(--color-brand)",
children,
}: {
/**
* Group title.
*/
title?: string;
/**
* Row count.
*/
rows: number;
/**
* Column count.
*/
columns: number;
/**
* Color. Must be a valid CSS color.
*/
color?: string;
/**
* Tiles.
*/
children: () => any;
} = $props();
// NOTE: to make it usable for small tiles
columns *= 2;
rows *= 2;
</script>
<section>
<!-- Group title -->
{#if title}
<h1 class="py-2 select-none">{title}</h1>
{/if}
<!-- Group content -->
<div
class="grid"
style="
--tile-color: {color};
grid-template-columns: repeat({columns}, 75px);
grid-template-rows: repeat({rows}, 75px);
"
>
{@render children()}
</div>
</section>

View file

@ -0,0 +1,13 @@
<script>
import iconSynzr from "$lib/assets/icons/synzr.webp";
import Tile from "$lib/components/tiles/Tile.svelte";
import TileGroup from "$lib/components/tiles/TileGroup.svelte";
</script>
<TileGroup title="a lot of mikhails" rows={3} columns={3}>
<Tile size="small" icon={iconSynzr} row={5} column={2} />
<Tile size="large" icon={iconSynzr} row={1} column={1} />
<Tile size="medium" icon={iconSynzr} row={3} column={5} />
<Tile size="wide" icon={iconSynzr} row={5} column={3} />
</TileGroup>

View file

@ -3,4 +3,5 @@
@theme {
--font-sans: 'Segoe UI', 'Open Sans Variable', sans-serif;
--font-mono: 'Cascadia Code Variable', monospace;
--color-brand: #ff695c;
}