|
|
- <template>
- <div class="picker-wrap">
- <!-- <pre style="position: fixed; z-index: 500; right: 0; top: 7rem; font-size: 0.6rem; color: orange;">
- {{ selectedAirport }}
- </pre> -->
- <label v-if="!origin">
- start here ►
- </label>
- <label v-if="origin">
- land here ■
- </label>
- <v-select
- :value="selectedAirportComp"
- label="iata"
- :options="airports"
- :filter-by="filterBy"
- :components="{OpenIndicator, Deselect}"
- @input="changeAirport"
- >
- <template #no-options="{ search, searching }">
- <template v-if="searching">
- We didn't find any airports or towns called <em>{{ search }}</em>.
- </template>
- <!-- <em
- v-else
- style="opacity: 0.5;"
- >
- Start typing to search for an airport.
- </em> -->
- </template>
- <template #selected-option="option">
- <div class="picker-item">
- <div class="picker-item__section">
- <div class="picker-item__iata">
- {{ option.iata }}
- </div>
- </div>
- <div class="picker-item__section">
- <div class="picker-item__name">
- {{ option.name }}
- </div>
- <div class="picker-item__muni">
- {{ option.municipality }}
- </div>
- </div>
- </div>
- </template>
- <template #option="option">
- <div class="picker-item">
- <div class="picker-item__section">
- <div class="picker-item__iata">
- {{ option.iata }}
- </div>
- </div>
- <div class="picker-item__section">
- <div class="picker-item__name">
- {{ option.name }}
- </div>
- <div class="picker-item__muni">
- {{ option.municipality }}
- </div>
- </div>
- </div>
- </template>
- <template #search="{ events, attributes }">
- <input
- :placeholder="placeholder"
- type="search"
- class="vs__search"
- v-bind="attributes"
- v-on="events"
- >
- </template>
- <template v-if="origin" #list-header>
- <li class="picker-warning">
- fly from <strong>{{ origin.iata }}</strong> to {{ airports.length > 1 ? "these" : "this" }} <strong>{{ airports.length }}</strong> {{ airports.length > 1 ? "airports" : "airport" }}
- </li>
- </template>
- </v-select>
- </div>
- </template>
-
- <script>
-
- import OpenIndicator from './OpenIndicator.vue'
- import Deselect from './Deselect.vue'
-
- export default {
- // ClearButton,
- props: {
- airports: {
- type: [Array],
- default () {
- return []
- }
- },
- selectedAirport: {
- type: [Object],
- default () {
- return {
- iata: '',
- lat: '',
- long: '',
- icon: '',
- name: '',
- municipality: '',
- type: '',
- search: ''
- }
- }
- },
- origin: {
- type: [Object],
- default () {
- return null
- }
- }
- },
- data: () => ({
- OpenIndicator,
- filterBy: (option, label, search) => {
- const temp = search.toLowerCase()
- return option.search.toLowerCase().includes(temp)
- }
- }),
- computed: {
- Deselect () {
- return this.selectedAirportComp.iata ? Deselect : ''
- },
- selectedAirportComp () {
- return {
- iata: this.selectedAirport.iata,
- lat: this.selectedAirport.lat,
- long: this.selectedAirport.long,
- icon: this.selectedAirport.icon,
- name: this.selectedAirport.name,
- municipality: this.selectedAirport.municipality,
- type: this.selectedAirport.type,
- search: this.selectedAirport.search,
- label: this.selectedAirport.label
- }
- },
- placeholder () {
- return (this.selectedAirport.iata) ? '' : 'town or airport'
- }
- },
- methods: {
- changeAirport (value) {
- if (value) {
- this.$emit('select-airport', value)
- } else {
- this.$emit('deselect-airport', value)
- }
- }
- }
- }
- </script>
-
- <style>
-
- .picker-wrap {
- margin: 1rem;
- position: relative;
- width: min(100vw - 2rem, 500px);
- }
-
- .picker-wrap:last-of-type {
- margin-top: 0;
- }
-
- .picker-wrap .vs__search {
- font-size: 3rem !important;
- padding: 0.5rem;
- }
-
- .vs__search::placeholder {
- color: #bbb;
- }
-
- .vs__dropdown-toggle {
- background: #eee;
- border: 0;
- border-radius: 0.5rem 3rem 3rem 3rem;
- padding-right: 0.5rem;
- padding-left: 0.5rem;
- padding-bottom: 0;
- }
-
- .vs__selected-options {
- padding: 0;
- }
-
- .picker-wrap .vs__search,
- .picker-wrap .vs__search:focus {
- margin: 0;
- }
-
- .picker-wrap .vs__actions {
- padding: 0;
- }
-
- .picker-item {
- padding: 0.5rem;
- display: flex;
- flex-direction: row;
- align-items: center;
- }
-
- .picker-item__section {
- display: flex;
- flex-direction: column;
- }
-
- .picker-item__name {
- font-size: 1rem;
- line-height: 1.1;
- white-space: normal;
- }
-
- .picker-item__muni {
- color: #007fff;
- line-height: 1.1;
- font-weight: 500;
- padding-top: 0.25rem;
- white-space: normal;
- }
-
- .picker-item__iata {
- font-size: 3rem;
- margin-right: 1rem;
- }
-
- .vs--single .vs__selected {
- position: absolute;
- }
-
- .vs__dropdown-option--highlight {
- background: #007fff;
- }
-
- .vs__dropdown-option--highlight .picker-item__muni {
- color: #eee;
- }
-
- </style>
-
- <style scoped>
-
- label {
- display: block;
- color: gray;
- position: absolute;
- z-index: 1;
- text-transform: uppercase;
- font-weight: 300;
- top: 0.3rem;
- left: 0.5rem;
- letter-spacing: 0.13rem;
- font-size: 0.8rem;
- }
-
- .picker-warning {
- background: hotpink;
- color: white;
- padding: 1rem;
- font-size: 1.5rem;
- pointer-events: none;
- }
-
- </style>
|