File size: 1,935 Bytes
fc7156e
5427205
 
 
fc7156e
5427205
 
 
 
 
 
4237e78
5427205
 
 
4237e78
fc7156e
5427205
 
 
 
 
 
 
 
4237e78
 
 
5427205
 
 
 
 
fc7156e
 
 
 
 
5427205
 
 
 
 
 
 
4237e78
5427205
fc7156e
 
 
5427205
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fc7156e
 
 
 
5427205
fc7156e
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<script lang="ts">
  import { createEventDispatcher, onMount } from 'svelte';
  import Fuse from 'fuse.js'
  const dispatch = createEventDispatcher();
  export let pos;
  export let boxes;
  let searchBox: HTMLInputElement;
  let hits = [];
  let selectedIndex = 0;
  onMount(() => searchBox.focus());
  const fuse = new Fuse(boxes, {
    keys: ['data.title']
  })
  function onInput() {
    hits = fuse.search(searchBox.value);
    selectedIndex = Math.max(0, Math.min(selectedIndex, hits.length - 1));
  }
  function onKeyDown(e) {
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      selectedIndex = Math.min(selectedIndex + 1, hits.length - 1);
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      selectedIndex = Math.max(selectedIndex - 1, 0);
    } else if (e.key === 'Enter') {
      const node = {...hits[selectedIndex].item};
      node.position = {x: pos.left, y: pos.top};
      dispatch('add', node);
    } else if (e.key === 'Escape') {
      dispatch('cancel');
    }
  }

</script>

<div class="node-search"
style="top: {pos.top}px; left: {pos.left}px; right: {pos.right}px; bottom: {pos.bottom}px;">

  <input
    bind:this={searchBox}
    on:input={onInput}
    on:keydown={onKeyDown}
    on:focusout={() => dispatch('cancel')}
    placeholder="Search for box">
  {#each hits as box, index}
    <div class="search-result" class:selected={index == selectedIndex}>{index} {box.item.data.title}</div>
  {/each}
</div>

<style>
  input {
    width: calc(100% - 26px);
    font-size: 20px;
    padding: 8px;
    border-radius: 4px;
    border: 1px solid #eee;
    margin: 4px;
  }
  .search-result {
    padding: 4px;
  }
  .search-result.selected {
    background-color: #f80;
    border-radius: 4px;
  }
  .node-search {
    position: absolute;
    width: 300px;
    z-index: 5;
    padding: 4px;
    border-radius: 4px;
    border: 1px solid #888;
    background-color: white;
  }
</style>