feature/tauri-v2
svelte 129 lines 3.4 KB
Raw
1 <script lang="ts">
2 import { ChevronDown } from "carbon-icons-svelte";
3 import { afterUpdate, createEventDispatcher, onMount } from "svelte";
4 const dispatch = createEventDispatcher();
5
6 export let label: string;
7 export let items = [
8 {id: 0, name: "No items listed"},
9 ];
10
11 let open = false;
12 let button;
13 let list;
14 export let selected = items[0].name;
15 const default_value = selected;
16
17 function handleSelect(item) {
18 const name = item.name;
19 selected = name;
20 dispatch("select", {selection: item});
21 }
22
23 afterUpdate(() => {
24 if (open && list) {
25 const { width, height, top } = list.getBoundingClientRect();
26 //list.style.width = `${width}px`;
27 //button.style.width = `${width}px`;
28 }
29 })
30
31 $: selected = items[0].name;
32 </script>
33
34 <svelte:window on:click={(e) => {
35 if (open && !button.contains(e.target)) {
36 open = false;
37 }
38 }}></svelte:window>
39
40 <div class="select">
41 <label for="selectButton" class="label">{label}:</label>
42 <div class="select-list" class:open>
43 <button name="selectButton" bind:this={button} on:click={() => {open = !open}}>
44 <span>{selected}</span>
45 <span class="arrow"><ChevronDown></ChevronDown></span>
46 </button>
47 {#if open}
48 <div bind:this={list} class="item-list">
49 {#each items as item}
50 <!-- svelte-ignore a11y-click-events-have-key-events -->
51 <div id={item.id.toString()} class="item" on:click={() => {
52 handleSelect(item);
53 open = false;
54 }}>
55 {item.name}
56 {#if default_value === item.name}
57 <span class="default">default</span>
58 {/if}
59 </div>
60 {/each}
61 </div>
62 {/if}
63 </div>
64 </div>
65
66 <style lang="scss">
67 .select {
68 display: flex;
69 flex-direction: column;
70 align-items: flex-start;
71 justify-content: center;
72 margin: 10px 0;
73 }
74 .label {
75 font-size: 0.9rem;
76 }
77 .open {
78 .arrow {
79 transform: rotateZ(180deg) !important;
80 }
81 }
82 .select-list {
83 min-width: 20rem;
84 button {
85 display: flex;
86 align-items: center;
87 justify-content: space-between;
88 min-height: 2rem;
89 width: 100%;
90 padding: 0 20px;
91 span {
92 display: flex;
93 align-items: center;
94 &:nth-child(1) {
95 margin-right: 5px;
96 }
97 &.arrow {
98 transform: rotateZ(0);
99 transition: 0.2s;
100 margin-top: 3px;
101 }
102 }
103 }
104 }
105 .item-list {
106 position: relative;
107 top: 1px;
108 max-height: 15rem;
109 overflow-y: overlay;
110 z-index: 1;
111 &::-webkit-scrollbar {
112 width: 12px;
113 }
114 &::-webkit-scrollbar-thumb {
115 background-color: #4c4c4c38;
116 }
117 .item {
118 display: flex;
119 align-items: center;
120 min-height: 2rem;
121 justify-content: space-between;
122 cursor: pointer;
123 padding: 0 20px;
124 }
125 }
126 .default {
127 color: #8c8c8c;
128 }
129 </style>