your personal website on atproto - mirror blento.app
at fix-500-on-first-login 115 lines 3.4 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 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 locked?: boolean; 21 fillPage?: boolean; 22 } & WithElementRef<HTMLAttributes<HTMLDivElement>>; 23 24 let { 25 item, 26 children, 27 ref = $bindable(null), 28 isEditing = false, 29 controls, 30 showOutline, 31 locked = false, 32 fillPage = false, 33 class: className, 34 ...rest 35 }: BaseCardProps = $props(); 36 37 let color = $derived(getColor(item)); 38</script> 39 40<div 41 id={item.id} 42 data-flip-id={item.id} 43 data-fill-page={fillPage ? 'true' : undefined} 44 bind:this={ref} 45 draggable={false} 46 class={[ 47 fillPage 48 ? 'card group/card selection:bg-accent-600/50 focus-within:outline-accent-500 @container/card relative isolate z-0 h-full w-full outline-offset-2 transition-all duration-200 focus-within:outline-2' 49 : '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', 50 !fillPage ? (color ? (colors[color] ?? colors.accent) : colors.base) : '', 51 color !== 'accent' && item.color !== 'base' && item.color !== 'transparent' ? color : '', 52 showOutline ? 'outline-2' : '', 53 className 54 ]} 55 style={` 56 --mx: ${item.mobileX}; 57 --my: ${item.mobileY}; 58 --mw: ${item.mobileW}; 59 --mh: ${item.mobileH}; 60 --mm: ${mobileMargin}px; 61 62 --dx: ${item.x}; 63 --dy: ${item.y}; 64 --dw: ${item.w}; 65 --dh: ${item.h}; 66 --dm: ${margin}px; 67 68 --columns: ${COLUMNS}`} 69 {...rest} 70> 71 <div 72 class={[ 73 'text-base-900 dark:text-base-50 relative isolate h-full w-full overflow-hidden', 74 !fillPage ? 'rounded-[23px]' : '', 75 color !== 'base' && color != 'transparent' ? 'light' : '' 76 ]} 77 > 78 {@render children?.()} 79 80 {#if !isEditing && item.cardData.label} 81 <div 82 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" 83 > 84 {item.cardData.label} 85 </div> 86 {/if} 87 </div> 88 {@render controls?.()} 89</div> 90 91<style> 92 .card { 93 container-name: card; 94 container-type: size; 95 translate: calc((var(--mx) / var(--columns)) * 100cqw + var(--mm)) 96 calc((var(--my) / var(--columns)) * 100cqw + var(--mm)); 97 width: calc((var(--mw) / var(--columns)) * 100cqw - (var(--mm) * 2)); 98 height: calc((var(--mh) / var(--columns)) * 100cqw - (var(--mm) * 2)); 99 } 100 101 .card[data-fill-page='true'] { 102 translate: none; 103 width: 100%; 104 height: 100%; 105 } 106 107 @container grid (width >= 42rem) { 108 .card:not([data-fill-page='true']) { 109 translate: calc((var(--dx) / var(--columns)) * 100cqw + var(--dm)) 110 calc((var(--dy) / var(--columns)) * 100cqw + var(--dm)); 111 width: calc((var(--dw) / var(--columns)) * 100cqw - (var(--dm) * 2)); 112 height: calc((var(--dh) / var(--columns)) * 100cqw - (var(--dm) * 2)); 113 } 114 } 115</style>