Skip to content

Commit

Permalink
finish dropdown widget
Browse files Browse the repository at this point in the history
  • Loading branch information
ZanyMonk committed Oct 13, 2021
1 parent 66c1f30 commit 6b5574e
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 14 deletions.
70 changes: 57 additions & 13 deletions src/components/DropdownSetting.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
</button>
<div class="field" v-show="visible">
<input type="text" ref="fieldInput"
v-model="value"
:placeholder="placeholder"
@keyup.esc="close()"
v-model="value"
@blur="close()"
@keyup.esc="close()"
@keyup.down="navigate(1)"
@keyup.up="navigate(-1)"
@keyup.enter="chooseSelected()"
@focusin="dropdownVisible = true"
>
<div :class="[{active: dropdownVisible}, 'arrow']"
Expand All @@ -21,7 +24,8 @@
<i class="bi-chevron-down"></i>
</div>
<div class="dropdown" v-show="dropdownVisible">
<div class="choice" v-for="(choice, name) in filteredChoices" :key="name"
<div v-for="(choice, name) in filteredChoices" :key="name"
:class="[{active: selected === name}, 'choice']"
@click="choose(choice)"
>
{{ choice.label }} ({{ choice.value }})
Expand All @@ -34,6 +38,9 @@
<script>
import {debounce} from 'debounce';
/**
* @TODO Abstract button-field widget
*/
export default {
name: 'DropdownSetting',
props: {
Expand All @@ -46,18 +53,20 @@ export default {
return {
value: '',
placeholder: '',
selected: null,
visible: false,
closedRecently: false,
dropdownVisible: true
}
},
computed: {
filteredChoices() {
if (!this.value) return this.setting.choices
const value = this.value
if (!value) return this.setting.choices
const choices = {}
for (const [name, choice] of Object.entries(this.setting.choices)) {
if (choice.label.toLowerCase().includes(this.value.toLowerCase())){
if (choice.label.toLowerCase().includes(value.toLowerCase())){
choices[name] = choice
}
}
Expand All @@ -75,20 +84,54 @@ export default {
}
},
close() {
this.visible = false
if (this.closedRecently) clearTimeout(this.closedRecently)
this.closedRecently = setTimeout(() => {
this.closedRecently = false
}, 500)
setTimeout(() => {
this.visible = false
this.selected = null
if (this.closedRecently) clearTimeout(this.closedRecently)
this.closedRecently = setTimeout(() => {
this.closedRecently = false
}, 500)
}, 200)
},
choose(choice) {
this.$emit('input', choice)
this.selected = choice
this.placeholder = `${choice.label} (${choice.value})`
this.value = ''
this.dropdownVisible = false
this.close()
},
navigate(step = 1) {
const choices = this.filteredChoices
const keys = Object.keys(choices)
if (!keys.length) return
let index = Math.max(0, keys.indexOf(this.selected))
if (index > -1 && this.selected) {
step = Math.max(-1, Math.min(step, 1))
const newIndex = (((index+step) % keys.length) + keys.length) % keys.length // Modulo that's not broken ...
this.selected = keys[newIndex]
} else {
this.selected = keys[step > 0 ? 0 : keys.length-1]
}
const choice = choices[this.selected]
this.$emit('input', choice)
this.placeholder = `${choice.label} (${choice.value})`
this.value = ''
},
chooseSelected() {
const choices = this.filteredChoices
console.log(choices, this.selected, this.selected in choices)
if (!this.selected || !(this.selected in choices)) this.value = choices[Object.keys(choices)[0]]
const choice = this.filteredChoices[this.selected]
this.$emit('input', choice)
this.placeholder = `${choice.label} (${choice.value})`
this.value = ''
this.close()
},
onButtonClicked: debounce(function () {
if (this.visible) this.close()
else this.open()
Expand Down Expand Up @@ -173,8 +216,9 @@ export default {
.choice {
cursor: pointer;
&:hover {
background: $decoder-border-color;
&:hover,
&.active {
background-color: $decoder-border-color;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/encoders/base64.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export class Base64 extends Encoder {
settings = {
mode: new MultichoiceSetting({
label: '',
alwaysShow: true,
value: null,
choices: {
standard: {
Expand Down
89 changes: 88 additions & 1 deletion src/scss/custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

*::-moz-selection,
*::selection {
background: #1fff5a !important;
background-color: #1fff5a;
}

.setting button {
Expand All @@ -17,4 +17,91 @@ textarea.no-wrap {
white-space: pre;
overflow-wrap: normal;
overflow-x: auto;
}

body.trololo {
&,
div,
button,
textarea {
animation: 1s linear infinite rainbow-bg, 1.5s linear infinite rainbow;
}
}

@keyframes rainbow-bg {
100%, 0% {
background-color: rgb(255, 0, 0);
}
8% {
background-color: rgb(255, 127, 0);
}
16% {
background-color: rgb(255, 255, 0);
}
25% {
background-color: rgb(127, 255, 0);
}
33% {
background-color: rgb(0, 255, 0);
}
41% {
background-color: rgb(0, 255, 127);
}
50% {
background-color: rgb(0, 255, 255);
}
58% {
background-color: rgb(0, 127, 255);
}
66% {
background-color: rgb(0, 0, 255);
}
75% {
background-color: rgb(127, 0, 255);
}
83% {
background-color: rgb(255, 0, 255);
}
91% {
background-color: rgb(255, 0, 127);
}
}

@keyframes rainbow {
100%, 0% {
color: rgb(255, 0, 0);
}
8% {
color: rgb(255, 127, 0);
}
16% {
color: rgb(255, 255, 0);
}
25% {
color: rgb(127, 255, 0);
}
33% {
color: rgb(0, 255, 0);
}
41% {
color: rgb(0, 255, 127);
}
50% {
color: rgb(0, 255, 255);
}
58% {
color: rgb(0, 127, 255);
}
66% {
color: rgb(0, 0, 255);
}
75% {
color: rgb(127, 0, 255);
}
83% {
color: rgb(255, 0, 255);
}
91% {
color: rgb(255, 0, 127);
}
}
1 change: 1 addition & 0 deletions src/types/GenericSetting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type SettingType = string | number | boolean | object;
export class GenericSetting<Type extends SettingType> implements Setting {
label: string
icon?: string
alwaysShow?: boolean = false
value: Type

constructor(config: SettingConfig) {
Expand Down
2 changes: 2 additions & 0 deletions src/types/Setting.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface Setting {
label: string
icon?: string
alwaysShow?: boolean
value: any

typeof(): string
Expand All @@ -9,6 +10,7 @@ export interface Setting {
export interface SettingConfig {
label: string
icon?: string
alwaysShow?: boolean
value: any
}

Expand Down

0 comments on commit 6b5574e

Please sign in to comment.