replies timeline only, appview-less bluesky client
1<script lang="ts"> 2 import type { Snippet } from 'svelte'; 3 4 interface Props { 5 isOpen: boolean; 6 onClose?: () => void; 7 title: string; 8 width?: string; 9 height?: string; 10 padding?: string; 11 showHeaderDivider?: boolean; 12 headerActions?: Snippet; 13 children: Snippet; 14 footer?: Snippet; 15 } 16 17 let { 18 isOpen = $bindable(false), 19 onClose = () => (isOpen = false), 20 title, 21 width = 'w-full max-w-md', 22 height = 'auto', 23 padding = 'p-4', 24 showHeaderDivider = false, 25 headerActions, 26 children, 27 footer 28 }: Props = $props(); 29 30 const handleKeydown = (event: KeyboardEvent) => { 31 if (event.key === 'Escape') onClose(); 32 }; 33</script> 34 35{#if isOpen} 36 <div 37 class="fixed inset-0 z-50 flex items-center justify-center bg-(--nucleus-bg)/80 backdrop-blur-sm" 38 onclick={onClose} 39 onkeydown={handleKeydown} 40 role="button" 41 tabindex="-1" 42 > 43 <!-- svelte-ignore a11y_interactive_supports_focus --> 44 <!-- svelte-ignore a11y_click_events_have_key_events --> 45 <div 46 class="flex {height === 'auto' 47 ? '' 48 : 'h-[' + 49 height + 50 ']'} {width} shrink animate-fade-in-scale flex-col rounded-sm border-2 border-(--nucleus-accent) bg-(--nucleus-bg) shadow-2xl transition-all" 51 style={height !== 'auto' ? `height: ${height}` : ''} 52 onclick={(e) => e.stopPropagation()} 53 role="dialog" 54 > 55 <!-- Header --> 56 <div 57 class="flex items-center gap-4 {showHeaderDivider 58 ? 'border-b-2 border-(--nucleus-accent)/20' 59 : ''} {padding}" 60 > 61 <div> 62 <h2 class="text-2xl font-bold">{title}</h2> 63 <div class="mt-2 flex gap-2"> 64 <div class="h-1 w-8 rounded-full bg-(--nucleus-accent)"></div> 65 <div class="h-1 w-9.5 rounded-full bg-(--nucleus-accent2)"></div> 66 </div> 67 </div> 68 69 {#if headerActions} 70 {@render headerActions()} 71 {/if} 72 73 <div class="grow"></div> 74 75 <!-- svelte-ignore a11y_consider_explicit_label --> 76 <button 77 onclick={onClose} 78 class="rounded-xl p-2 text-(--nucleus-fg)/40 transition-all hover:scale-110 hover:text-(--nucleus-fg)" 79 > 80 <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> 81 <path 82 stroke-linecap="round" 83 stroke-linejoin="round" 84 stroke-width="2.5" 85 d="M6 18L18 6M6 6l12 12" 86 /> 87 </svg> 88 </button> 89 </div> 90 91 <!-- Content --> 92 <div class="{height === 'auto' ? '' : 'flex-1 overflow-y-auto'} {padding}"> 93 {@render children()} 94 </div> 95 96 <!-- Footer --> 97 {#if footer} 98 {@render footer()} 99 {/if} 100 </div> 101 </div> 102{/if}