|
1 | 1 | <script lang="ts"> |
2 | 2 | import { clickOnEnter } from '$lib/helpers/a11y'; |
3 | 3 | import { createCombobox, melt } from '@melt-ui/svelte'; |
| 4 | +
|
4 | 5 | import { createEventDispatcher, onMount } from 'svelte'; |
5 | 6 | import { Label } from '.'; |
6 | 7 |
|
|
46 | 47 | } |
47 | 48 | return next; |
48 | 49 | }, |
49 | | - preventScroll: false |
| 50 | + preventScroll: false, |
| 51 | + closeOnOutsideClick: false |
50 | 52 | }); |
51 | 53 |
|
52 | 54 | $: { |
|
59 | 61 | $: selectedOption = options.find((option) => option.value === value); |
60 | 62 | $: selectedOption && innerSelected.set(selectedOption); |
61 | 63 |
|
62 | | - let element: HTMLInputElement; |
| 64 | + let inputEl: HTMLInputElement; |
| 65 | + let menuEl: HTMLElement; |
| 66 | + let wrapperEl: HTMLElement; |
63 | 67 | let hasFocus = false; |
64 | 68 |
|
65 | 69 | const dispatch = createEventDispatcher(); |
66 | 70 |
|
67 | 71 | onMount(() => { |
68 | | - if (element && autofocus) { |
69 | | - element.focus(); |
| 72 | + if (inputEl && autofocus) { |
| 73 | + inputEl.focus(); |
70 | 74 | } |
71 | 75 | }); |
72 | 76 |
|
|
85 | 89 | $: console.log(disabled); |
86 | 90 | </script> |
87 | 91 |
|
| 92 | +<svelte:window |
| 93 | + on:click={function clickOutside(e) { |
| 94 | + const el = e.target; |
| 95 | + if (!(el instanceof HTMLElement || el instanceof SVGElement)) { |
| 96 | + open.set(false); |
| 97 | + return; |
| 98 | + } |
| 99 | + |
| 100 | + if (!menuEl || !wrapperEl) return; |
| 101 | + |
| 102 | + if (!wrapperEl.contains(el) && !menuEl.contains(el)) { |
| 103 | + hasFocus = false; |
| 104 | + $open = false; |
| 105 | + } |
| 106 | + }} /> |
| 107 | + |
88 | 108 | <div |
89 | 109 | class="u-position-relative form-item" |
90 | 110 | class:u-width-full-line={fullWidth} |
91 | | - class:u-stretch={stretch}> |
| 111 | + class:u-stretch={stretch} |
| 112 | + bind:this={wrapperEl}> |
92 | 113 | <Label {required} {hideRequired} {optionalText} hide={!showLabel} for={id} {tooltip}> |
93 | 114 | {label} |
94 | 115 | </Label> |
|
112 | 133 | {placeholder} |
113 | 134 | {required} |
114 | 135 | on:input={handleInput} |
115 | | - bind:this={element} |
| 136 | + bind:this={inputEl} |
116 | 137 | use:melt={$input} /> |
117 | 138 | {/if} |
118 | 139 |
|
|
133 | 154 | disabled={!interactiveOutput} |
134 | 155 | on:click={() => { |
135 | 156 | hasFocus = !hasFocus; |
136 | | - open.set(true); |
| 157 | + $open = !$open; |
137 | 158 | }}> |
138 | 159 | <span class="icon-cheveron-down" aria-hidden="true" /> |
139 | 160 | </button> |
140 | 161 | </div> |
141 | 162 | </div> |
142 | 163 |
|
143 | | - <div class="drop-wrapper" use:melt={$menu}> |
| 164 | + <div class="drop-wrapper" use:melt={$menu} bind:this={menuEl}> |
144 | 165 | <div class="drop is-no-arrow"> |
145 | 166 | <section class="drop-section"> |
146 | 167 | <ul class="drop-list"> |
|
0 commit comments