| 
					
				 | 
			
			
				@@ -0,0 +1,223 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+<script lang="ts" setup> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { ref, onBeforeUnmount, computed } from "vue"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	useFloating, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	offset, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	flip, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	shift, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	autoUpdate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	arrow 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} from "@floating-ui/vue"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const reference = ref(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const floating = ref(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const floatingArrow = ref(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const isOpen = ref(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const { placement, floatingStyles, middlewareData } = useFloating( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	reference, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	floating, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		placement: "left", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		middleware: [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			offset(10), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			flip(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			shift(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			arrow({ element: floatingArrow }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		whileElementsMounted: autoUpdate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const arrowStyles = computed(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	const staticStyles = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		left: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			middlewareData.value?.arrow?.x != null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				? `${middlewareData.value.arrow.x}px` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				: "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		top: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			middlewareData.value?.arrow?.y != null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				? `${middlewareData.value.arrow.y}px` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				: "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch (placement.value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "left": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				...staticStyles, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				right: "-8px" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "right": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				...staticStyles, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				left: "-8px" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "top": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				...staticStyles, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				bottom: "-8px" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "bottom": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				...staticStyles, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				top: "-8px" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const collapse = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	isOpen.value = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// eslint-disable-next-line no-use-before-define 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	document.removeEventListener("click", handleClickOutside); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const expand = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	isOpen.value = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// eslint-disable-next-line no-use-before-define 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	document.addEventListener("click", handleClickOutside); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const toggle = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (isOpen.value) collapse(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	else expand(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const handleClickOutside = (event: MouseEvent) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		floating.value && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		!floating.value.contains(event.target) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		!reference.value.contains(event.target) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		collapse(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+defineExpose({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	expand, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	collapse, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	toggle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+onBeforeUnmount(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (isOpen.value) collapse(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+</script> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+<template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	<div ref="reference" class="dropdown-list__reference" @click="toggle"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		<slot /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	<div 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		v-if="isOpen" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		ref="floating" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		class="dropdown-list__floating" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		:style="floatingStyles" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		<ul class="dropdown-list__list"> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			<slot name="options" /> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		</ul> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		<div 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			ref="floatingArrow" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			class="dropdown-list__arrow" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			:class="`dropdown-list__arrow--placement-${placement}`" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			:style="arrowStyles" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		></div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	</div> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+</template> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+<style lang="less" scoped> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+.dropdown-list { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	--light-grey-1: #d4d4d4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	&__floating { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		position: fixed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		top: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		left: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		width: 180px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		z-index: 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		background-color: var(--white); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		color: var(--black); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		border: solid 1px var(--light-grey-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		border-radius: 5px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		box-shadow: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			0 14px 28px rgba(0, 0, 0, 0.25), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			0 10px 10px rgba(0, 0, 0, 0.22); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	&__list { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		display: flex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		flex-direction: column; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		max-height: 300px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		overflow-y: auto; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		margin: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		padding: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	&__arrow { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		position: absolute; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		width: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		height: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		border: 8px solid transparent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		pointer-events: none; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		&::before { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			content: ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			position: absolute; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			border: 8px solid transparent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		&--placement-left { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			border-left-color: var(--light-grey-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			border-right: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			&::before { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				top: -8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				left: -9px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				border-left-color: var(--white); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				border-right: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		&--placement-right { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			border-right-color: var(--light-grey-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			border-left: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			&::before { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				top: -8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				right: -9px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				border-right-color: var(--white); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				border-left: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		&--placement-top { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			border-top-color: var(--light-grey-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			border-bottom: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			&::before { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				top: -9px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				left: -8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				border-top-color: var(--white); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				border-bottom: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		&--placement-bottom { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			border-bottom-color: var(--light-grey-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			border-top: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			&::before { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				bottom: -9px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				left: -8px; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				border-bottom-color: var(--white); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				border-top: 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+</style> 
			 |