Create Modal component
This commit is contained in:
		
							parent
							
								
									c3ee1f807a
								
							
						
					
					
						commit
						18831d2e3f
					
				|  | @ -7,5 +7,9 @@ | ||||||
| 	"[svelte]": { | 	"[svelte]": { | ||||||
| 		"editor.defaultFormatter": "svelte.svelte-vscode" | 		"editor.defaultFormatter": "svelte.svelte-vscode" | ||||||
| 	}, | 	}, | ||||||
| 	"typescript.tsdk": "node_modules\\typescript\\lib" | 	"typescript.tsdk": "node_modules\\typescript\\lib", | ||||||
|  | 	"svelte.plugin.svelte.compilerWarnings": { | ||||||
|  | 		"a11y-no-noninteractive-element-interactions": "ignore", | ||||||
|  | 		"a11y-click-events-have-key-events": "ignore" | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -56,6 +56,10 @@ ol > li { | ||||||
| 	list-style: decimal; | 	list-style: decimal; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | html.modal-is-open { | ||||||
|  | 	scrollbar-gutter: stable; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| body:has(.bytemd-fullscreen) { | body:has(.bytemd-fullscreen) { | ||||||
| 	overflow: hidden; | 	overflow: hidden; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,55 @@ | ||||||
|  | <script lang="ts"> | ||||||
|  | 	import Button from './button.svelte'; | ||||||
|  | 	import FaXmark from '$icon/fa-xmark.svelte'; | ||||||
|  | 
 | ||||||
|  | 	export let open: boolean; | ||||||
|  | 	export let title: string; | ||||||
|  | 	export let size: 'sm' | 'md' | 'lg' = 'md'; | ||||||
|  | 
 | ||||||
|  | 	const maxWidths = { | ||||||
|  | 		sm: '400px', | ||||||
|  | 		md: '700px', | ||||||
|  | 		lg: '1000px', | ||||||
|  | 	} satisfies Record<typeof size, `${number}px`>; | ||||||
|  | 
 | ||||||
|  | 	$: { | ||||||
|  | 		const docClassList = document.documentElement.classList; | ||||||
|  | 		const openClasses = ['modal-is-open', 'modal-is-opening']; | ||||||
|  | 		docClassList[open ? 'add' : 'remove'](...openClasses); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	function close() { | ||||||
|  | 		open = false; | ||||||
|  | 	} | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <dialog {open} on:click={close} class="app-modal"> | ||||||
|  | 	<article style:--max-width={maxWidths[size]} on:click|stopPropagation> | ||||||
|  | 		<header> | ||||||
|  | 			{title} | ||||||
|  | 			<div class="app-modal__spacer" /> | ||||||
|  | 			<Button plain icon size="lg" label="Close" tooltipPlacement={null} on:click={close}> | ||||||
|  | 				<FaXmark /> | ||||||
|  | 			</Button> | ||||||
|  | 		</header> | ||||||
|  | 		<slot /> | ||||||
|  | 	</article> | ||||||
|  | </dialog> | ||||||
|  | 
 | ||||||
|  | <style lang="scss"> | ||||||
|  | 	.app-modal { | ||||||
|  | 		article { | ||||||
|  | 			max-width: var(--max-width, none); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		header { | ||||||
|  | 			font-size: 1.2rem; | ||||||
|  | 			display: flex; | ||||||
|  | 			align-items: center; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		&__spacer { | ||||||
|  | 			flex-grow: 1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | </style> | ||||||
		Loading…
	
		Reference in New Issue