your personal website on atproto - mirror
blento.app
1<script lang="ts">
2 import { COLUMNS, margin, mobileMargin } from '$lib';
3 import type { Item } from '$lib/types';
4 import type { WithElementRef } from 'bits-ui';
5 import type { Snippet } from 'svelte';
6 import type { HTMLAttributes } from 'svelte/elements';
7 import { getColor } from '..';
8
9 const colors = {
10 base: 'bg-base-200/50 dark:bg-base-950/50',
11 accent: 'bg-accent-400 dark:bg-accent-500 accent',
12 transparent: ''
13 } as Record<string, string>;
14
15 export type BaseCardProps = {
16 item: Item;
17 controls?: Snippet<[]>;
18 isEditing?: boolean;
19 showOutline?: boolean;
20 } & WithElementRef<HTMLAttributes<HTMLDivElement>>;
21
22 let {
23 item,
24 children,
25 ref = $bindable(null),
26 isEditing = false,
27 controls,
28 showOutline,
29 class: className,
30 ...rest
31 }: BaseCardProps = $props();
32
33 let color = $derived(getColor(item));
34</script>
35
36<div
37 id={item.id}
38 data-flip-id={item.id}
39 bind:this={ref}
40 draggable={isEditing}
41 class={[
42 'card group/card selection:bg-accent-600/50 focus-within:outline-accent-500 @container/card absolute isolate z-0 rounded-3xl outline-offset-2 transition-all duration-200 focus-within:outline-2',
43 color ? (colors[color] ?? colors.accent) : colors.base,
44 color !== 'accent' && item.color !== 'base' && item.color !== 'transparent' ? color : '',
45 showOutline ? 'outline-2' : '',
46 className
47 ]}
48 style={`
49 --mx: ${item.mobileX};
50 --my: ${item.mobileY};
51 --mw: ${item.mobileW};
52 --mh: ${item.mobileH};
53 --mm: ${mobileMargin}px;
54
55 --dx: ${item.x};
56 --dy: ${item.y};
57 --dw: ${item.w};
58 --dh: ${item.h};
59 --dm: ${margin}px;
60
61 --columns: ${COLUMNS}`}
62 {...rest}
63>
64 <div
65 class={[
66 'text-base-900 dark:text-base-50 relative isolate h-full w-full overflow-hidden rounded-[23px]',
67 color !== 'base' && color != 'transparent' ? 'light' : ''
68 ]}
69 >
70 {@render children?.()}
71 </div>
72 {@render controls?.()}
73</div>
74
75<style>
76 .card {
77 translate: calc((var(--mx) / var(--columns)) * 100cqw + var(--mm))
78 calc((var(--my) / var(--columns)) * 100cqw + var(--mm));
79 width: calc((var(--mw) / var(--columns)) * 100cqw - (var(--mm) * 2));
80 height: calc((var(--mh) / var(--columns)) * 100cqw - (var(--mm) * 2));
81 }
82
83 @container grid (width >= 42rem) {
84 .card {
85 translate: calc((var(--dx) / var(--columns)) * 100cqw + var(--dm))
86 calc((var(--dy) / var(--columns)) * 100cqw + var(--dm));
87 width: calc((var(--dw) / var(--columns)) * 100cqw - (var(--dm) * 2));
88 height: calc((var(--dh) / var(--columns)) * 100cqw - (var(--dm) * 2));
89 }
90 }
91</style>