your personal website on atproto - mirror blento.app
at card-command-bar-v2 111 lines 3.1 kB view raw
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 import { getIsCoarse } from '$lib/website/context'; 9 10 function tryGetIsCoarse(): (() => boolean) | undefined { 11 try { 12 return getIsCoarse(); 13 } catch { 14 return undefined; 15 } 16 } 17 const isCoarse = tryGetIsCoarse(); 18 19 const colors = { 20 base: 'bg-base-200/50 dark:bg-base-950/50', 21 accent: 'bg-accent-400 dark:bg-accent-500 accent', 22 transparent: '' 23 } as Record<string, string>; 24 25 export type BaseCardProps = { 26 item: Item; 27 controls?: Snippet<[]>; 28 isEditing?: boolean; 29 showOutline?: boolean; 30 locked?: boolean; 31 } & WithElementRef<HTMLAttributes<HTMLDivElement>>; 32 33 let { 34 item, 35 children, 36 ref = $bindable(null), 37 isEditing = false, 38 controls, 39 showOutline, 40 locked = false, 41 class: className, 42 ...rest 43 }: BaseCardProps = $props(); 44 45 let color = $derived(getColor(item)); 46</script> 47 48<div 49 id={item.id} 50 data-flip-id={item.id} 51 bind:this={ref} 52 draggable={isEditing && !locked && !isCoarse?.()} 53 class={[ 54 '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', 55 color ? (colors[color] ?? colors.accent) : colors.base, 56 color !== 'accent' && item.color !== 'base' && item.color !== 'transparent' ? color : '', 57 showOutline ? 'outline-2' : '', 58 className 59 ]} 60 style={` 61 --mx: ${item.mobileX}; 62 --my: ${item.mobileY}; 63 --mw: ${item.mobileW}; 64 --mh: ${item.mobileH}; 65 --mm: ${mobileMargin}px; 66 67 --dx: ${item.x}; 68 --dy: ${item.y}; 69 --dw: ${item.w}; 70 --dh: ${item.h}; 71 --dm: ${margin}px; 72 73 --columns: ${COLUMNS}`} 74 {...rest} 75> 76 <div 77 class={[ 78 'text-base-900 dark:text-base-50 relative isolate h-full w-full overflow-hidden rounded-[23px]', 79 color !== 'base' && color != 'transparent' ? 'light' : '' 80 ]} 81 > 82 {@render children?.()} 83 84 {#if !isEditing && item.cardData.label} 85 <div 86 class="text-base-900 dark:text-base-50 bg-base-200/50 dark:bg-base-900/50 absolute top-2 left-2 z-30 max-w-[calc(100%-1rem)] rounded-xl p-1 px-2 text-base font-semibold backdrop-blur-md" 87 > 88 {item.cardData.label} 89 </div> 90 {/if} 91 </div> 92 {@render controls?.()} 93</div> 94 95<style> 96 .card { 97 translate: calc((var(--mx) / var(--columns)) * 100cqw + var(--mm)) 98 calc((var(--my) / var(--columns)) * 100cqw + var(--mm)); 99 width: calc((var(--mw) / var(--columns)) * 100cqw - (var(--mm) * 2)); 100 height: calc((var(--mh) / var(--columns)) * 100cqw - (var(--mm) * 2)); 101 } 102 103 @container grid (width >= 42rem) { 104 .card { 105 translate: calc((var(--dx) / var(--columns)) * 100cqw + var(--dm)) 106 calc((var(--dy) / var(--columns)) * 100cqw + var(--dm)); 107 width: calc((var(--dw) / var(--columns)) * 100cqw - (var(--dm) * 2)); 108 height: calc((var(--dh) / var(--columns)) * 100cqw - (var(--dm) * 2)); 109 } 110 } 111</style>