You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 lines
4.9 KiB

  1. <template>
  2. <div class="picker-wrap">
  3. <!-- <pre style="position: fixed; z-index: 500; right: 0; top: 7rem; font-size: 0.6rem; color: orange;">
  4. {{ selectedAirport }}
  5. </pre> -->
  6. <label for="">
  7. {{ leg }}
  8. </label>
  9. <v-select
  10. :value="selectedAirportComp"
  11. label="iata"
  12. :options="airports"
  13. :filter-by="filterBy"
  14. :components="{OpenIndicator, Deselect}"
  15. @input="changeAirport"
  16. >
  17. <template #no-options="{ search, searching }">
  18. <template v-if="searching">
  19. No results found for <em>{{ search }}</em>.
  20. </template>
  21. <em
  22. v-else
  23. style="opacity: 0.5;"
  24. >
  25. Start typing to search for an airport.
  26. </em>
  27. </template>
  28. <template #selected-option="option">
  29. <div class="picker-item">
  30. <div class="picker-item__section">
  31. <div class="picker-item__iata">
  32. {{ option.iata }}
  33. </div>
  34. </div>
  35. <div class="picker-item__section">
  36. <div class="picker-item__name">
  37. {{ option.name }}
  38. </div>
  39. <div class="picker-item__muni">
  40. {{ option.municipality }}
  41. </div>
  42. </div>
  43. </div>
  44. </template>
  45. <template #option="option">
  46. <div class="picker-item">
  47. <div class="picker-item__section">
  48. <div class="picker-item__iata">
  49. {{ option.iata }}
  50. </div>
  51. </div>
  52. <div class="picker-item__section">
  53. <div class="picker-item__name">
  54. {{ option.name }}
  55. </div>
  56. <div class="picker-item__muni">
  57. {{ option.municipality }}
  58. </div>
  59. </div>
  60. </div>
  61. </template>
  62. <template #search="{ events, attributes }">
  63. <input
  64. :placeholder="placeholder"
  65. type="search"
  66. class="vs__search"
  67. v-bind="attributes"
  68. v-on="events"
  69. >
  70. </template>
  71. </v-select>
  72. </div>
  73. </template>
  74. <script>
  75. import OpenIndicator from './OpenIndicator.vue'
  76. import Deselect from './Deselect.vue'
  77. export default {
  78. // ClearButton,
  79. props: {
  80. airports: {
  81. type: [Array],
  82. default () {
  83. return []
  84. }
  85. },
  86. selectedAirport: {
  87. type: [Object],
  88. default () {
  89. return {
  90. iata: '',
  91. lat: '',
  92. long: '',
  93. icon: '',
  94. name: '',
  95. municipality: '',
  96. type: '',
  97. search: ''
  98. }
  99. }
  100. },
  101. leg: {
  102. type: [String],
  103. default () {
  104. return ''
  105. }
  106. }
  107. },
  108. data: () => ({
  109. OpenIndicator,
  110. filterBy: (option, label, search) => {
  111. const temp = search.toLowerCase()
  112. return option.search.toLowerCase().includes(temp)
  113. }
  114. }),
  115. computed: {
  116. Deselect () {
  117. return this.selectedAirportComp.iata ? Deselect : ''
  118. },
  119. selectedAirportComp () {
  120. return {
  121. iata: this.selectedAirport.iata,
  122. lat: this.selectedAirport.lat,
  123. long: this.selectedAirport.long,
  124. icon: this.selectedAirport.icon,
  125. name: this.selectedAirport.name,
  126. municipality: this.selectedAirport.municipality,
  127. type: this.selectedAirport.type,
  128. search: this.selectedAirport.search,
  129. label: this.selectedAirport.label
  130. }
  131. },
  132. placeholder () {
  133. return (this.selectedAirport.iata) ? '' : 'town or airport'
  134. }
  135. },
  136. methods: {
  137. changeAirport (value) {
  138. if (value) {
  139. this.$emit('select-airport', value)
  140. } else {
  141. this.$emit('deselect-airport', value)
  142. }
  143. }
  144. }
  145. }
  146. </script>
  147. <style>
  148. .picker-wrap {
  149. margin: 1rem;
  150. position: relative;
  151. width: min(100vw - 2rem, 500px);
  152. }
  153. .picker-wrap:last-of-type {
  154. margin-top: 0;
  155. }
  156. .picker-wrap .vs__search {
  157. font-size: 3rem !important;
  158. padding: 0.5rem;
  159. }
  160. .vs__search::placeholder {
  161. color: #bbb;
  162. }
  163. .vs__dropdown-toggle {
  164. background: #eee;
  165. border: 0;
  166. border-radius: 0.5rem 3rem 3rem 3rem;
  167. padding-right: 0.5rem;
  168. padding-left: 0.5rem;
  169. padding-bottom: 0;
  170. }
  171. .vs__selected-options {
  172. padding: 0;
  173. }
  174. .picker-wrap .vs__search,
  175. .picker-wrap .vs__search:focus {
  176. margin: 0;
  177. }
  178. .picker-wrap .vs__actions {
  179. padding: 0;
  180. }
  181. .picker-item {
  182. padding: 0.5rem;
  183. display: flex;
  184. flex-direction: row;
  185. align-items: center;
  186. }
  187. .picker-item__section {
  188. display: flex;
  189. flex-direction: column;
  190. }
  191. .picker-item__name {
  192. font-size: 1rem;
  193. line-height: 1.1;
  194. white-space: normal;
  195. }
  196. .picker-item__muni {
  197. color: #007fff;
  198. line-height: 1.1;
  199. padding-top: 0.25rem;
  200. white-space: normal;
  201. }
  202. .picker-item__iata {
  203. font-size: 3rem;
  204. margin-right: 1rem;
  205. }
  206. .vs--single .vs__selected {
  207. position: absolute;
  208. }
  209. </style>
  210. <style scoped>
  211. label {
  212. display: block;
  213. color: gray;
  214. position: absolute;
  215. z-index: 1;
  216. text-transform: uppercase;
  217. font-weight: 300;
  218. top: 0.3rem;
  219. left: 0.5rem;
  220. letter-spacing: 0.13rem;
  221. font-size: 0.8rem;
  222. }
  223. </style>