@stonecrop/aform 0.3.10 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- .aform_checkbox[data-v-9f382ad4]{cursor:pointer;width:auto;margin-top:0;display:block}.aform_checkbox[data-v-9f382ad4]:checked{accent-color:var(--sc-primary-color);border:1px solid black}.aform_checkbox-container[data-v-9f382ad4]{width:100%;display:inline-block;text-align:left}.aform_checkbox-container input[data-v-9f382ad4]{width:auto}.aform_checkbox-container:hover+.aform_field-label[data-v-9f382ad4]{color:var(--sc-input-active-label-color)}div[data-v-280b3d1a]{min-width:40ch;width:100%;box-sizing:border-box;border:1px solid transparent;padding:0rem;margin:0rem;margin-right:1ch}input[data-v-280b3d1a]{width:calc(100% - 1ch);box-sizing:border-box;outline:1px solid transparent;border:1px solid var(--sc-input-border-color);padding:1ch .5ch .5ch 1ch;margin:.575rem 0 0;min-height:1.15rem;border-radius:.25rem}p[data-v-280b3d1a],label[data-v-280b3d1a]{color:var(--sc-input-label-color);display:block;min-height:1.15rem;padding:0rem;margin:0rem 0rem .25rem;border:1px solid transparent;box-sizing:border-box}p[data-v-280b3d1a]{width:100%;color:red;font-size:85%;box-sizing:border-box}label[data-v-280b3d1a]{z-index:2;font-size:80%;position:absolute;background:#fff;margin:-2.575rem 0 0 1ch;padding:0 .25ch;box-sizing:border-box}input[data-v-280b3d1a]:focus{border:1px solid var(--sc-input-active-border-color)}input:focus+label[data-v-280b3d1a]{color:var(--sc-input-active-label-color)}.autocomplete[data-v-4e77785f]{position:relative}.input-wrapper[data-v-4e77785f]{min-width:40ch;border:1px solid transparent;padding:0rem;margin:0rem;margin-right:1ch}input[data-v-4e77785f]{width:calc(100% - 1ch);outline:1px solid transparent;border:1px solid var(--sc-input-border-color);padding:1ch .5ch .5ch 1ch;margin:.575rem 0 0;min-height:1.15rem;border-radius:.25rem}input[data-v-4e77785f]:focus{border:1px solid var(--sc-input-active-border-color);border-radius:.25rem .25rem 0 0;border-bottom:none}label[data-v-4e77785f]{display:block;min-height:1.15rem;padding:0rem;margin:0rem 0rem .25rem;border:1px solid transparent;z-index:2;font-size:80%;position:absolute;background:#fff;margin:-2.575rem 0 0 1ch;padding:0 .25ch}.autocomplete-results[data-v-4e77785f]{position:absolute;width:calc(100% - 1ch + 1.5px);z-index:1;padding:0;margin:0;color:#000;border:1px solid var(--sc-input-active-border-color);border-radius:0 0 .25rem .25rem;border-top:none}.autocomplete-result[data-v-4e77785f]{list-style:none;text-align:left;padding:4px 6px;cursor:pointer}.autocomplete-result.is-active[data-v-4e77785f],.autocomplete-result[data-v-4e77785f]:hover{background-color:var(--sc-row-color-zebra-light);color:#000}.adatepicker[data-v-f49cfd40]{font-size:var(--sc-table-font-size);display:inline-table;color:var(--sc-cell-text-color);outline:none;border-collapse:collapse}.adatepicker tr[data-v-f49cfd40]{height:1.15rem;text-align:center;vertical-align:middle}.adatepicker td[data-v-f49cfd40]{border:2px solid transparent;outline:2px solid transparent;min-width:3ch;max-width:3ch}.adatepicker td[data-v-f49cfd40]:focus,.adatepicker td[data-v-f49cfd40]:focus-within{outline:1px dashed black;box-shadow:none;min-height:1.15em;max-height:1.15em;overflow:hidden}.adatepicker .selectedDate[data-v-f49cfd40]{outline:1px solid black;background:var(--sc-gray-20);font-weight:bolder}.adatepicker .todaysDate[data-v-f49cfd40]{font-weight:bolder;text-decoration:underline;color:#000}.days-header>td[data-v-f49cfd40]{font-weight:700}.prev-date[data-v-f49cfd40]{color:var(--sc-gray-20)}.collapse-button[data-v-6f1c1b45]{width:2ch;min-width:calc(66px - 4ch);background-color:transparent;font-size:150%;text-align:center;border:none;margin-top:-.5rem}.rotated[data-v-6f1c1b45]{transform:rotate(45deg);-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transition:transform .25s;transform-origin:center center}.unrotated[data-v-6f1c1b45]{transform:rotate(0);-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transition:transform .25s}.aform_form-element{padding:0;margin:0;position:relative;box-sizing:border-box;flex-grow:1;min-width:20ch;margin-bottom:1rem}.aform_input-field{outline:1px solid var(--sc-input-border-color);outline-offset:-1px;font-size:1rem;padding:.5rem;margin:0;border-radius:0;box-sizing:border-box;width:100%;min-height:auto;position:relative;color:var(--sc-cell-text-color);background:var(--sc-input-field-background)}.aform_input-field:focus{outline:1px solid var(--sc-input-active-border-color)}.aform_input-field:focus+.aform_field-label{color:var(--sc-input-active-label-color)}.aform_field-label{color:var(--sc-input-label-color);display:inline-block;position:absolute;padding:0 .25rem;margin:0rem;z-index:2;font-size:.7rem;font-weight:300;letter-spacing:.05rem;background:linear-gradient(var(--sc-form-background) 50%,var(--sc-input-field-background) 50%);width:auto;box-sizing:border-box;background:#fff;margin:0;grid-row:1;top:0;left:10px;border:none;line-height:0;transform:translateY(-50%)}.aform_input-field:disabled{background:var(--sc-input-field-disabled-background)}.aform_input-field:disabled+.aform_field-label{background:linear-gradient(var(--sc-form-background) 50%,var(--sc-input-field-disabled-background) 50%)}.aform_input-field:disabled~p.aform_error{background:linear-gradient(var(--sc-form-background) 50%,var(--sc-input-field-disabled-background) 50%)}.aform_field-label:after{margin:0;padding:0;box-sizing:border-box;content:"";line-height:normal}p.aform_error{display:block;display:inline-block;display:none;background:linear-gradient(var(--sc-form-background) 50%,var(--sc-input-field-background) 50%);padding:0 .25rem;margin:0rem;width:auto;color:var(--sc-brand-danger);font-size:.7rem;position:absolute;right:0;top:0;line-height:0;background:#fff;padding:.25rem;transform:translate(-1rem,-50%);margin:0}.aform[data-v-68845234]{display:flex;flex-wrap:wrap;gap:1rem;padding:1rem;border:1px solid var(--sc-form-border);border-left:4px solid var(--sc-form-border);margin-bottom:1rem;max-width:100%}@media screen and (max-width: 400px){.aform[data-v-68845234]{flex-direction:column}}fieldset[data-v-e7ea7e12]{max-width:100%;width:100%;margin-right:2ch;border:1px solid transparent;border-bottom:1px solid var(--sc-gray-50)}legend[data-v-e7ea7e12]{width:100%;height:1.15rem;border:1px solid transparent;padding-bottom:.5rem;font-size:110%;font-weight:600;-webkit-user-select:none;user-select:none}.collapse-button[data-v-e7ea7e12]{float:right}.aform_file-attach[data-v-0b3a11cc]{padding:1rem;display:flex;flex-wrap:wrap;gap:1rem;flex-direction:row;justify-content:center;align-items:center;border:1px dashed var(--sc-input-border-color);width:100%}@media screen and (max-width: 400px){.aform_file-attach>.aform_form-btn[data-v-0b3a11cc]{width:100%}}.aform_file-attach-feedback[data-v-0b3a11cc]{color:var(--sc-input-label-color);width:100%;padding:.5rem;text-align:center;align-self:center}.aform_file-attach-feedback>li[data-v-0b3a11cc]{list-style:none;font-style:italic}.aform_file-attach-feedback>p[data-v-0b3a11cc]{margin-top:0}.aform_form-btn[data-v-0b3a11cc]{padding:.5rem 2rem;width:auto;border:1px solid var(--sc-input-border-color);color:var(--sc-input-label-color);cursor:pointer;background-color:#fff}.aform_form-btn[data-v-0b3a11cc]:disabled{background-color:var(--sc-gray-5)}.login-container[data-v-6cbd3add]{width:100%;position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;font-family:var(--sc-font-family)}.account-container[data-v-6cbd3add]{width:100%;margin-left:auto;margin-top:.5rem;margin-right:auto;display:flex;flex-direction:column;justify-content:center}.account-header[data-v-6cbd3add]{display:flex;flex-direction:column;text-align:center;margin-top:.5rem}#account-title[data-v-6cbd3add]{font-size:1.5rem;line-height:2rem;font-weight:600;letter-spacing:-.025em;margin:0}#account-subtitle[data-v-6cbd3add]{font-size:.875rem;line-height:1.25rem;margin:1rem}.login-form-container[data-v-6cbd3add]{display:grid;gap:.5rem}.login-form-element[data-v-6cbd3add]{display:grid;margin:.5rem 0;position:relative}.login-field[data-v-6cbd3add]{padding:.5rem .25rem .25rem .5rem;outline:1px solid transparent;border:1px solid var(--sc-input-border-color);border-radius:.25rem}.login-field[data-v-6cbd3add]:focus{border:1px solid black}.btn[data-v-6cbd3add]{background-color:var(--sc-btn-color);color:var(--sc-btn-label-color);border:1px solid var(--sc-btn-border);margin:.5rem 0;padding:.25rem;position:relative;cursor:pointer}.btn[data-v-6cbd3add]:hover{background-color:var(--sc-btn-hover)}.btn[data-v-6cbd3add]:disabled{background-color:var(--sc-input-field-disabled-background)}.disabled[data-v-6cbd3add]{opacity:.5}.loading-icon[data-v-6cbd3add]{animation:spin-6cbd3add 1s linear infinite forwards;display:inline-block;margin-right:.2rem;line-height:0;font-size:1rem;position:relative;top:.2rem}@keyframes spin-6cbd3add{0%{transform:rotate(0)}to{transform:rotate(360deg)}}
1
+ .aform_checkbox[data-v-9f382ad4]{cursor:pointer;width:auto;margin-top:0;display:block}.aform_checkbox[data-v-9f382ad4]:checked{accent-color:var(--sc-primary-color);border:1px solid black}.aform_checkbox-container[data-v-9f382ad4]{width:100%;display:inline-block;text-align:left}.aform_checkbox-container input[data-v-9f382ad4]{width:auto}.aform_checkbox-container:hover+.aform_field-label[data-v-9f382ad4]{color:var(--sc-input-active-label-color)}div[data-v-280b3d1a]{min-width:40ch;width:100%;box-sizing:border-box;border:1px solid transparent;padding:0rem;margin:0rem;margin-right:1ch}input[data-v-280b3d1a]{width:calc(100% - 1ch);box-sizing:border-box;outline:1px solid transparent;border:1px solid var(--sc-input-border-color);padding:1ch .5ch .5ch 1ch;margin:.575rem 0 0;min-height:1.15rem;border-radius:.25rem}p[data-v-280b3d1a],label[data-v-280b3d1a]{color:var(--sc-input-label-color);display:block;min-height:1.15rem;padding:0rem;margin:0rem 0rem .25rem;border:1px solid transparent;box-sizing:border-box}p[data-v-280b3d1a]{width:100%;color:red;font-size:85%;box-sizing:border-box}label[data-v-280b3d1a]{z-index:2;font-size:80%;position:absolute;background:#fff;margin:-2.575rem 0 0 1ch;padding:0 .25ch;box-sizing:border-box}input[data-v-280b3d1a]:focus{border:1px solid var(--sc-input-active-border-color)}input:focus+label[data-v-280b3d1a]{color:var(--sc-input-active-label-color)}.autocomplete[data-v-16c329d1]{position:relative}.input-wrapper[data-v-16c329d1]{border:1px solid transparent;padding:0rem;margin:0rem;margin-right:1ch}input[data-v-16c329d1]{width:calc(100% - 1ch);outline:1px solid transparent;border:1px solid var(--sc-input-border-color);padding:1ch .5ch .5ch 1ch;margin:.575rem 0 0;min-height:1.15rem;border-radius:.25rem}input[data-v-16c329d1]:focus{border:1px solid var(--sc-input-active-border-color);border-radius:.25rem .25rem 0 0;border-bottom:none}label[data-v-16c329d1]{display:block;min-height:1.15rem;padding:0rem;margin:0rem 0rem .25rem;border:1px solid transparent;z-index:2;font-size:80%;position:absolute;background:#fff;margin:-2.575rem 0 0 1ch;padding:0 .25ch}.autocomplete-results[data-v-16c329d1]{position:absolute;width:calc(100% - 1ch + 1.5px);z-index:999;padding:0;margin:0;color:var(--sc-input-active-border-color);border:1px solid var(--sc-input-active-border-color);border-radius:0 0 .25rem .25rem;border-top:none;background-color:#fff}.autocomplete-result[data-v-16c329d1]{list-style:none;text-align:left;padding:4px 6px;cursor:pointer;border-bottom:.5px solid lightgray}.autocomplete-result.is-active[data-v-16c329d1],.autocomplete-result[data-v-16c329d1]:hover{background-color:var(--sc-row-color-zebra-light);color:var(--sc-input-active-border-color)}.adatepicker[data-v-f49cfd40]{font-size:var(--sc-table-font-size);display:inline-table;color:var(--sc-cell-text-color);outline:none;border-collapse:collapse}.adatepicker tr[data-v-f49cfd40]{height:1.15rem;text-align:center;vertical-align:middle}.adatepicker td[data-v-f49cfd40]{border:2px solid transparent;outline:2px solid transparent;min-width:3ch;max-width:3ch}.adatepicker td[data-v-f49cfd40]:focus,.adatepicker td[data-v-f49cfd40]:focus-within{outline:1px dashed black;box-shadow:none;min-height:1.15em;max-height:1.15em;overflow:hidden}.adatepicker .selectedDate[data-v-f49cfd40]{outline:1px solid black;background:var(--sc-gray-20);font-weight:bolder}.adatepicker .todaysDate[data-v-f49cfd40]{font-weight:bolder;text-decoration:underline;color:#000}.days-header>td[data-v-f49cfd40]{font-weight:700}.prev-date[data-v-f49cfd40]{color:var(--sc-gray-20)}.collapse-button[data-v-6f1c1b45]{width:2ch;min-width:calc(66px - 4ch);background-color:transparent;font-size:150%;text-align:center;border:none;margin-top:-.5rem}.rotated[data-v-6f1c1b45]{transform:rotate(45deg);-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transition:transform .25s;transform-origin:center center}.unrotated[data-v-6f1c1b45]{transform:rotate(0);-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transition:transform .25s}.aform_form-element{padding:0;margin:0;position:relative;box-sizing:border-box;flex-grow:1;min-width:20ch;margin-bottom:1rem}.aform_input-field{outline:1px solid var(--sc-input-border-color);outline-offset:-1px;font-size:1rem;padding:.5rem;margin:0;border-radius:0;box-sizing:border-box;width:100%;min-height:auto;position:relative;color:var(--sc-cell-text-color);background:var(--sc-input-field-background)}.aform_input-field:focus{outline:1px solid var(--sc-input-active-border-color)}.aform_input-field:focus+.aform_field-label{color:var(--sc-input-active-label-color)}.aform_field-label{color:var(--sc-input-label-color);display:inline-block;position:absolute;padding:0 .25rem;margin:0rem;z-index:2;font-size:.7rem;font-weight:300;letter-spacing:.05rem;background:linear-gradient(var(--sc-form-background) 50%,var(--sc-input-field-background) 50%);width:auto;box-sizing:border-box;background:#fff;margin:0;grid-row:1;top:0;left:10px;border:none;line-height:0;transform:translateY(-50%)}.aform_input-field:disabled{background:var(--sc-input-field-disabled-background)}.aform_input-field:disabled+.aform_field-label{background:linear-gradient(var(--sc-form-background) 50%,var(--sc-input-field-disabled-background) 50%)}.aform_input-field:disabled~p.aform_error{background:linear-gradient(var(--sc-form-background) 50%,var(--sc-input-field-disabled-background) 50%)}.aform_field-label:after{margin:0;padding:0;box-sizing:border-box;content:"";line-height:normal}p.aform_error{display:block;display:inline-block;display:none;background:linear-gradient(var(--sc-form-background) 50%,var(--sc-input-field-background) 50%);padding:0 .25rem;margin:0rem;width:auto;color:var(--sc-brand-danger);font-size:.7rem;position:absolute;right:0;top:0;line-height:0;background:#fff;padding:.25rem;transform:translate(-1rem,-50%);margin:0}.aform[data-v-68845234]{display:flex;flex-wrap:wrap;gap:1rem;padding:1rem;border:1px solid var(--sc-form-border);border-left:4px solid var(--sc-form-border);margin-bottom:1rem;max-width:100%}@media screen and (max-width: 400px){.aform[data-v-68845234]{flex-direction:column}}fieldset[data-v-e7ea7e12]{max-width:100%;width:100%;margin-right:2ch;border:1px solid transparent;border-bottom:1px solid var(--sc-gray-50)}legend[data-v-e7ea7e12]{width:100%;height:1.15rem;border:1px solid transparent;padding-bottom:.5rem;font-size:110%;font-weight:600;-webkit-user-select:none;user-select:none}.collapse-button[data-v-e7ea7e12]{float:right}.aform_file-attach[data-v-0b3a11cc]{padding:1rem;display:flex;flex-wrap:wrap;gap:1rem;flex-direction:row;justify-content:center;align-items:center;border:1px dashed var(--sc-input-border-color);width:100%}@media screen and (max-width: 400px){.aform_file-attach>.aform_form-btn[data-v-0b3a11cc]{width:100%}}.aform_file-attach-feedback[data-v-0b3a11cc]{color:var(--sc-input-label-color);width:100%;padding:.5rem;text-align:center;align-self:center}.aform_file-attach-feedback>li[data-v-0b3a11cc]{list-style:none;font-style:italic}.aform_file-attach-feedback>p[data-v-0b3a11cc]{margin-top:0}.aform_form-btn[data-v-0b3a11cc]{padding:.5rem 2rem;width:auto;border:1px solid var(--sc-input-border-color);color:var(--sc-input-label-color);cursor:pointer;background-color:#fff}.aform_form-btn[data-v-0b3a11cc]:disabled{background-color:var(--sc-gray-5)}.login-container[data-v-6cbd3add]{width:100%;position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;font-family:var(--sc-font-family)}.account-container[data-v-6cbd3add]{width:100%;margin-left:auto;margin-top:.5rem;margin-right:auto;display:flex;flex-direction:column;justify-content:center}.account-header[data-v-6cbd3add]{display:flex;flex-direction:column;text-align:center;margin-top:.5rem}#account-title[data-v-6cbd3add]{font-size:1.5rem;line-height:2rem;font-weight:600;letter-spacing:-.025em;margin:0}#account-subtitle[data-v-6cbd3add]{font-size:.875rem;line-height:1.25rem;margin:1rem}.login-form-container[data-v-6cbd3add]{display:grid;gap:.5rem}.login-form-element[data-v-6cbd3add]{display:grid;margin:.5rem 0;position:relative}.login-field[data-v-6cbd3add]{padding:.5rem .25rem .25rem .5rem;outline:1px solid transparent;border:1px solid var(--sc-input-border-color);border-radius:.25rem}.login-field[data-v-6cbd3add]:focus{border:1px solid black}.btn[data-v-6cbd3add]{background-color:var(--sc-btn-color);color:var(--sc-btn-label-color);border:1px solid var(--sc-btn-border);margin:.5rem 0;padding:.25rem;position:relative;cursor:pointer}.btn[data-v-6cbd3add]:hover{background-color:var(--sc-btn-hover)}.btn[data-v-6cbd3add]:disabled{background-color:var(--sc-input-field-disabled-background)}.disabled[data-v-6cbd3add]{opacity:.5}.loading-icon[data-v-6cbd3add]{animation:spin-6cbd3add 1s linear infinite forwards;display:inline-block;margin-right:.2rem;line-height:0;font-size:1rem;position:relative;top:.2rem}@keyframes spin-6cbd3add{0%{transform:rotate(0)}to{transform:rotate(360deg)}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stonecrop/aform",
3
- "version": "0.3.10",
3
+ "version": "0.3.11",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "author": {
@@ -32,9 +32,10 @@
32
32
  ],
33
33
  "dependencies": {
34
34
  "@vueuse/core": "^12.0.0",
35
+ "@vueuse/components": "^12.0.0",
35
36
  "vue": "^3.5.11",
36
- "@stonecrop/themes": "0.3.10",
37
- "@stonecrop/utilities": "0.3.10"
37
+ "@stonecrop/themes": "0.3.11",
38
+ "@stonecrop/utilities": "0.3.11"
38
39
  },
39
40
  "devDependencies": {
40
41
  "@microsoft/api-documenter": "^7.26.2",
@@ -55,11 +56,11 @@
55
56
  "vite": "^5.4.5",
56
57
  "vitest": "^2.1.1",
57
58
  "vue-router": "^4.4.0",
58
- "@stonecrop/atable": "0.3.10",
59
- "stonecrop-rig": "0.2.22"
59
+ "stonecrop-rig": "0.2.22",
60
+ "@stonecrop/atable": "0.3.11"
60
61
  },
61
62
  "peerDependencies": {
62
- "@stonecrop/atable": "0.3.10"
63
+ "@stonecrop/atable": "0.3.11"
63
64
  },
64
65
  "publishConfig": {
65
66
  "access": "public"
@@ -1,25 +1,26 @@
1
1
  <template>
2
- <div class="autocomplete" :class="{ isOpen: isOpen }">
2
+ <div class="autocomplete" :class="{ isOpen: dropdown.open }" v-on-click-outside="onClickOutside">
3
3
  <div class="input-wrapper">
4
4
  <input
5
- ref="mopInput"
6
- type="text"
7
- @input="onChange"
8
- @focus="onChange"
9
5
  v-model="search"
10
- @keydown.down="onArrowDown"
11
- @keydown.up="onArrowUp"
12
- @keydown.enter="onEnter" />
13
-
14
- <ul id="autocomplete-results" v-show="isOpen" class="autocomplete-results">
15
- <li class="loading autocomplete-result" v-if="isLoading">Loading results...</li>
6
+ type="text"
7
+ @input="filter"
8
+ @focus="openDropdown"
9
+ @keydown.down="selectNextResult"
10
+ @keydown.up="selectPrevResult"
11
+ @keydown.enter="setCurrentResult"
12
+ @keydown.esc="onClickOutside"
13
+ @keydown.tab="onClickOutside" />
14
+
15
+ <ul id="autocomplete-results" v-show="dropdown.open" class="autocomplete-results">
16
+ <li class="loading autocomplete-result" v-if="dropdown.loading">Loading results...</li>
16
17
  <li
17
18
  v-else
18
- v-for="(result, i) in results"
19
- :key="i"
20
- @click="setResult(result)"
19
+ v-for="(result, i) in dropdown.results"
20
+ :key="result"
21
+ @click.stop="setResult(result)"
21
22
  class="autocomplete-result"
22
- :class="{ 'is-active': i === arrowCounter }">
23
+ :class="{ 'is-active': i === dropdown.activeItemIndex }">
23
24
  {{ result }}
24
25
  </li>
25
26
  </ul>
@@ -29,94 +30,99 @@
29
30
  </template>
30
31
 
31
32
  <script setup lang="ts">
32
- import { onMounted, onUnmounted, ref /* useTemplateRef */ } from 'vue'
33
+ import { vOnClickOutside } from '@vueuse/components'
34
+ import { reactive } from 'vue'
33
35
 
34
- const { label, items, isAsync } = defineProps<{
36
+ const { label, items, isAsync, filterFunction } = defineProps<{
35
37
  label: string
36
38
  items?: string[]
37
39
  isAsync?: boolean
40
+ filterFunction?: (search: string) => string[] | Promise<string[]>
38
41
  }>()
39
-
40
- const emit = defineEmits(['filterChanged'])
41
-
42
- const results = ref(items)
43
42
  const search = defineModel<string>()
44
- const isLoading = ref(false)
45
- const arrowCounter = ref(0)
46
- const isOpen = ref(false)
47
- // const mopInput = useTemplateRef<HTMLInputElement>('mopInput')
48
-
49
- onMounted(() => {
50
- document.addEventListener('click', handleClickOutside)
51
- filterResults()
52
- })
53
43
 
54
- onUnmounted(() => {
55
- document.removeEventListener('click', handleClickOutside)
44
+ const dropdown = reactive({
45
+ activeItemIndex: null as number | null,
46
+ open: false,
47
+ loading: false,
48
+ results: items,
56
49
  })
57
50
 
58
- const setResult = result => {
59
- search.value = result
60
- closeResults()
61
- }
62
-
63
- const filterResults = () => {
64
- if (!search.value) {
65
- results.value = items
66
- } else {
67
- results.value = items.filter(item => {
68
- return item.toLowerCase().indexOf(search.value.toLowerCase()) > -1
69
- })
70
- }
71
- }
72
-
73
- const onChange = () => {
74
- isOpen.value = true
75
- if (isAsync) {
76
- isLoading.value = true
77
- emit('filterChanged', search.value)
51
+ const onClickOutside = () => closeDropdown()
52
+
53
+ const filter = async () => {
54
+ dropdown.open = true
55
+ if (filterFunction) {
56
+ if (isAsync) dropdown.loading = true
57
+ try {
58
+ const filteredResults = await filterFunction(search.value || '')
59
+ dropdown.results = filteredResults
60
+ } catch {
61
+ dropdown.results = []
62
+ } finally {
63
+ if (isAsync) dropdown.loading = false
64
+ }
78
65
  } else {
79
66
  filterResults()
80
67
  }
81
68
  }
82
69
 
83
- const handleClickOutside = () => {
84
- closeResults()
85
- arrowCounter.value = 0
70
+ const setResult = (result: string) => {
71
+ search.value = result
72
+ closeDropdown(result)
86
73
  }
87
74
 
88
- const closeResults = () => {
89
- isOpen.value = false
75
+ const openDropdown = () => {
76
+ dropdown.activeItemIndex = isAsync ? null : search.value ? items?.indexOf(search.value) || null : null
77
+ dropdown.open = true
78
+ // TODO: this should probably call the async function if it's async
79
+ dropdown.results = isAsync ? [] : items
80
+ }
90
81
 
91
- // TODO: (test) when would this occur? how should this be tested?
92
- if (!items.includes(search.value)) {
82
+ const closeDropdown = (result?: string) => {
83
+ dropdown.activeItemIndex = null
84
+ dropdown.open = false
85
+ if (!items?.includes(result || search.value || '')) {
93
86
  search.value = ''
94
87
  }
95
88
  }
96
89
 
97
- const onArrowDown = () => {
98
- if (arrowCounter.value < results.value.length) {
99
- arrowCounter.value = arrowCounter.value + 1
90
+ const filterResults = () => {
91
+ if (!search.value) {
92
+ dropdown.results = items
93
+ } else {
94
+ dropdown.results = items?.filter(item => item.toLowerCase().includes((search.value ?? '').toLowerCase()))
100
95
  }
101
96
  }
102
97
 
103
- const onArrowUp = () => {
104
- if (arrowCounter.value > 0) {
105
- arrowCounter.value = arrowCounter.value - 1
98
+ const selectNextResult = () => {
99
+ const resultsLength = dropdown.results?.length || 0
100
+ if (dropdown.activeItemIndex != null) {
101
+ const currentIndex = isNaN(dropdown.activeItemIndex) ? 0 : dropdown.activeItemIndex
102
+ dropdown.activeItemIndex = (currentIndex + 1) % resultsLength
103
+ } else {
104
+ dropdown.activeItemIndex = 0
106
105
  }
107
106
  }
108
107
 
109
- const onEnter = () => {
110
- search.value = results.value[arrowCounter.value]
111
- closeResults()
112
- arrowCounter.value = 0
108
+ const selectPrevResult = () => {
109
+ const resultsLength = dropdown.results?.length || 0
110
+ if (dropdown.activeItemIndex != null) {
111
+ const currentIndex = isNaN(dropdown.activeItemIndex) ? 0 : dropdown.activeItemIndex
112
+ dropdown.activeItemIndex = (currentIndex - 1 + resultsLength) % resultsLength
113
+ } else {
114
+ dropdown.activeItemIndex = resultsLength - 1
115
+ }
113
116
  }
114
117
 
115
- // const openWithSearch = () => {
116
- // search.value = ''
117
- // onChange()
118
- // mopInput.value.focus()
119
- // }
118
+ const setCurrentResult = () => {
119
+ if (dropdown.results) {
120
+ const currentIndex = dropdown.activeItemIndex || 0
121
+ const result = dropdown.results[currentIndex]
122
+ setResult(result)
123
+ }
124
+ dropdown.activeItemIndex = 0
125
+ }
120
126
  </script>
121
127
 
122
128
  <style scoped>
@@ -126,7 +132,6 @@ const onEnter = () => {
126
132
  }
127
133
 
128
134
  .input-wrapper {
129
- min-width: 40ch;
130
135
  border: 1px solid transparent;
131
136
  padding: 0rem;
132
137
  margin: 0rem;
@@ -167,13 +172,14 @@ label {
167
172
  .autocomplete-results {
168
173
  position: absolute;
169
174
  width: calc(100% - 1ch + 1.5px);
170
- z-index: 1;
175
+ z-index: 999;
171
176
  padding: 0;
172
177
  margin: 0;
173
- color: #000000;
178
+ color: var(--sc-input-active-border-color);
174
179
  border: 1px solid var(--sc-input-active-border-color);
175
180
  border-radius: 0 0 0.25rem 0.25rem;
176
181
  border-top: none;
182
+ background-color: #fff;
177
183
  }
178
184
 
179
185
  .autocomplete-result {
@@ -181,11 +187,12 @@ label {
181
187
  text-align: left;
182
188
  padding: 4px 6px;
183
189
  cursor: pointer;
190
+ border-bottom: 0.5px solid lightgray;
184
191
  }
185
192
 
186
193
  .autocomplete-result.is-active,
187
194
  .autocomplete-result:hover {
188
195
  background-color: var(--sc-row-color-zebra-light);
189
- color: #000000;
196
+ color: var(--sc-input-active-border-color);
190
197
  }
191
198
  </style>