Aktualizacja scenerii i wyglądu select boxów

This commit is contained in:
2021-05-30 16:01:31 +02:00
parent 1a1c4b3006
commit adc61d8061
6 changed files with 218 additions and 2342 deletions
+121 -73
View File
@@ -1,33 +1,50 @@
<template>
<div class="select-box">
<div class="select-box_content">
<label>
<select
v-model="selectedItem"
:style="bgColor ? 'background-color:' + bgColor : ''"
>
<option value disabled selected hidden>
{{ title }}
</option>
<option v-for="item in itemList" :key="item.id" :value="item.id">
{{ item.value }}
</option>
</select>
<span class="arrows"></span>
</label>
<button class="selected" @click="toggleBox">
{{ selectedItemComp ? selectedItemComp.value : "" }}
</button>
<div class="options" v-if="boxVisible">
<div class="option" v-for="item in itemList" :key="item.id">
<label :for="item.id">
<input
type="button"
:id="item.id"
name="select-box"
@click="selectOption(item)"
/>
<span :style="selectedItemComp.id == item.id ? 'color: gold;' : ''">
{{ item.value }}
</span>
</label>
</div>
</div>
</div>
<div class="arrow">
<img :src="boxVisible ? ascIcon : descIcon" alt="arrow-icon" />
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch, Emit } from "vue-property-decorator";
import { Component, Vue, Prop, Emit } from "vue-property-decorator";
@Component
export default class SelectBox extends Vue {
@Prop({ required: true }) title!: string;
@Prop({ required: true }) itemList!: { id: string | number; value: string }[];
@Prop({ default: 0 }) defaultItemIndex!: number;
@Prop() bgColor!: string;
boxVisible = false;
test() {
console.log("test");
}
@Emit("selected")
onItemSelected() {
return this.selectedItem;
@@ -36,10 +53,21 @@ export default class SelectBox extends Vue {
ascIcon = require("@/assets/icon-arrow-asc.svg");
descIcon = require("@/assets/icon-arrow-desc.svg");
selectedItem: string = "";
selectedItem: { id: string | number; value: string } | null = null;
@Watch("selectedItem")
watchSelectedItem(item) {
get selectedItemComp() {
if (!this.selectedItem) return this.itemList[this.defaultItemIndex];
return this.itemList.find((item) => item.id === this.selectedItem?.id);
}
toggleBox() {
this.boxVisible = !this.boxVisible;
}
selectOption(item: { id: string | number; value: string }) {
this.selectedItem = item;
this.boxVisible = false;
this.onItemSelected();
}
}
@@ -49,80 +77,100 @@ export default class SelectBox extends Vue {
@import "../../styles/variables.scss";
.select-box {
&_content {
// display: inline-block;
position: relative;
}
position: relative;
margin: 0.5em auto;
.arrow {
position: absolute;
top: 50%;
right: 0.5em;
img {
vertical-align: middle;
width: 1.35em;
}
select {
border: none;
outline: none;
transform: translateY(-50%);
background: #333;
padding: 0.35em 0.5em;
padding-right: 2em;
border-radius: 0.5em;
pointer-events: none;
}
font-size: 1em;
color: white;
.select-box_content {
position: relative;
margin: 0 auto;
appearance: none;
-moz-appearance: none;
-webkit-appearance: none;
min-width: 10em;
cursor: pointer;
background: #333;
transition: all 0.3s;
text-align: center;
}
&:focus {
// border: 1px solid red;
.options {
position: absolute;
top: 100%;
left: 0;
background: #777;
z-index: 10;
option {
background: #333;
}
}
}
width: 100%;
label {
position: relative;
}
margin-top: 0.25em;
}
.arrows {
$arrowCol: #d8d8d8;
$arrowWidth: 0.35em;
button.selected {
background: #333;
color: white;
position: absolute;
top: 20%;
// right: 0.25em;
font-size: 1em;
pointer-events: none;
padding: 0.35em 0.5em;
padding-right: 2em;
&::before,
&::after {
content: "";
width: 0;
height: 0;
width: 100%;
cursor: pointer;
position: absolute;
right: 0.5em;
border: none;
outline: none;
border-left: $arrowWidth solid transparent;
border-right: $arrowWidth solid transparent;
}
text-align: left;
&::before {
border-top: $arrowWidth solid $arrowCol;
transform: translateY(150%);
}
&::after {
border-bottom: $arrowWidth solid $arrowCol;
}
&:focus {
background: #555;
}
}
input {
position: absolute;
top: 0;
left: 0;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: none;
&:focus + span {
color: $accentCol;
font-weight: bold;
}
}
label {
position: relative;
display: inline-block;
background: #333;
&:hover,
&:focus {
background: #555;
}
padding: 0.25em 0;
width: 100%;
cursor: pointer;
}
</style>
+24 -14
View File
@@ -16,18 +16,19 @@
</a>
</h3>
<select-box
v-if="stationInfo && stationInfo.checkpoints"
:title="selectedOption"
:itemList="
stationInfo.checkpoints.map((cp, i) => ({
id: cp.checkpointName,
value: cp.checkpointName,
}))
"
bgColor="#444"
@selected="chooseOption"
></select-box>
<div class="checkpoints">
<select-box
v-if="stationInfo && stationInfo.checkpoints"
:title="selectedOption"
:itemList="
stationInfo.checkpoints.map((cp, i) => ({
id: cp.checkpointName,
value: cp.checkpointName,
}))
"
@selected="chooseOption"
></select-box>
</div>
<span class="timetable-item loading" v-if="dataStatus == 0">{{
$t("app.loading")
@@ -162,8 +163,8 @@ export default class SceneryTimetable extends Vue {
this.loadSelectedOption();
}
chooseOption(name: string) {
this.selectedOption = name;
chooseOption(item: { id: number | string; value: string }) {
this.selectedOption = item.value;
}
get currentURL() {
@@ -381,6 +382,15 @@ h3 {
}
}
.checkpoints {
display: flex;
justify-content: center;
& > div {
border: 1px solid white;
}
}
.arrow {
border: solid white;
border-width: 0 2px 2px 0;
+7 -2
View File
@@ -4,6 +4,7 @@
<select-box
:title="$t('trains.option-distance')"
:itemList="translatedSorterOptions"
:defaultItemIndex="3"
@selected="changeSorter"
/>
@@ -104,8 +105,8 @@ export default class TrainOptions extends Vue {
}
@Emit()
changeSorter(optionID: string) {
return { id: optionID, dir: -1 };
changeSorter(item: { id: string | number; value: string }) {
return { id: item.id, dir: -1 };
}
/* Watchers for search boxes */
@@ -155,6 +156,10 @@ export default class TrainOptions extends Vue {
}
}
.select-box {
margin-top: 0.5em;
}
.search {
&-box {
position: relative;