Something went wrong. Try again.
your personal website on atproto - mirror blento.app
Something went wrong. Try again.
4.1 kB · 154 lines
Svelte
at commit 2b9e4dfd
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155<script lang="ts"> import type { Item } from '$lib/types'; import type { EditingSectionContentProps } from '../types'; import { EditableGrid, fixCollisions, compactItems, setPositionOfNewItem } from '$lib/layout'; import GridBaseEditingCard from '$lib/cards/_base/BaseCard/GridBaseEditingCard.svelte'; import EditingCard from '$lib/cards/_base/Card/EditingCard.svelte'; import SectionChrome from '../SectionChrome.svelte'; import { GRID_SECTION_ICON, GRID_SECTION_NAME } from './shared'; import { positionItemAtGridPos } from './add-item';
let { section, items = $bindable(), isMobile, selectedCardId, isCoarse, isActive, onlayoutchange, ondeselect, onrequestaddcard, oncreatefilecards, onactivate, onrefchange }: EditingSectionContentProps = $props();
let gridRef: HTMLDivElement | undefined = $state();
let sectionItems = $derived(items.filter((i) => i.sectionId === section.id));
let hovered = $state(false);
$effect(() => { onrefchange(gridRef); return () => onrefchange(undefined); });
$effect(() => { const el = gridRef; if (!el) return;
const enter = () => (hovered = true); const leave = () => (hovered = false); const down = () => onactivate();
el.addEventListener('pointerenter', enter); el.addEventListener('pointerleave', leave); el.addEventListener('pointerdown', down);
return () => { el.removeEventListener('pointerenter', enter); el.removeEventListener('pointerleave', leave); el.removeEventListener('pointerdown', down); }; });
async function handleFileDrop(files: File[], gridX: number, gridY: number) { const cards = await oncreatefilecards(files); for (let i = 0; i < cards.length; i++) { const card = cards[i]; card.sectionId = section.id; if (i === 0) { positionItemAtGridPos(card, gridX, gridY, isMobile); } else { const currentSectionItems = items.filter((it) => it.sectionId === section.id); setPositionOfNewItem(card, currentSectionItems); }
items = [...items, card]; const updatedSectionItems = items.filter((it) => it.sectionId === section.id); fixCollisions(updatedSectionItems, card, isMobile); fixCollisions(updatedSectionItems, card, !isMobile); } onlayoutchange(); }</script>
<EditableGrid items={sectionItems} bind:ref={gridRef} {isMobile} {selectedCardId} {isCoarse} {onlayoutchange} {ondeselect} onfiledrop={handleFileDrop}> <SectionChrome sectionId={section.id} {isActive} {hovered} name={section.name || GRID_SECTION_NAME} icon={GRID_SECTION_ICON} />
{#if sectionItems.length === 0} <div class="border-base-300/50 dark:border-base-700/50 pointer-events-auto relative flex min-h-32 items-center justify-center rounded-3xl border-2 border-dashed" > <button type="button" class="text-base-400 dark:text-base-500 hover:text-accent-500 flex cursor-pointer items-center gap-2 text-sm transition-colors" onclick={() => onrequestaddcard()} > <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4"><path d="M12 5v14" /><path d="M5 12h14" /></svg > Add a card </button> </div> {/if}
{#each sectionItems as item (item.id)} {@const idx = items.indexOf(item)} <GridBaseEditingCard bind:item={items[idx]} ondelete={() => { items = items.filter((it) => it !== item); compactItems( items.filter((i) => i.sectionId === section.id), false ); compactItems( items.filter((i) => i.sectionId === section.id), true ); onlayoutchange(); }} onsetsize={(newW, newH) => { if (isMobile) { item.mobileW = newW; item.mobileH = newH; } else { item.w = newW; item.h = newH; } fixCollisions( items.filter((i) => i.sectionId === section.id), item, isMobile ); onlayoutchange(); }} > <EditingCard bind:item={items[idx]} /> </GridBaseEditingCard> {/each}</EditableGrid>