Ui components for radiobuttons and textarea

This commit is contained in:
2019-12-26 00:43:10 +01:00
parent a2c00d929d
commit 841ee4327e
2 changed files with 212 additions and 0 deletions

View File

@@ -0,0 +1,133 @@
<template>
<div>
<label v-for="option in options" class="radio" @click="selected = option.value">
<input type="radio" v-model="selected" :value="option.value" />
<label>{{ option.text }}</label>
<div class="sub-radios" v-if="option.subElements && selected === option.value">
<label class="radio" v-for="elem in option.subElements">
<input type="radio" v-model="selectedSubItem" :value="option.value + '-' + elem.value" />
<label>{{ elem.text }}</label>
</label>
</div>
</label>
</div>
</template>
<script>
export default {
props: {
options: {
type: Array,
required: true
},
value: {
required: false,
default: undefined
}
},
data() {
return {
selected: this.value || this.options[0].value,
selectedSubItem: null
};
},
beforeMount() {
this.handleChange()
},
watch: {
selected() {
this.handleChange();
}
},
methods: {
handleChange() {
if (this.value !== undefined) {
this.$emit("update:value", this.selected);
} else {
this.$emit("changed", this.selected);
}
}
}
};
</script>
<style lang="scss" scoped>
@import "./src/scss/variables.scss";
$radioSize: 16px;
$ui-border-width: 2px;
.sub-radios {
display: flex;
flex-direction: column;
flex: 0 0 100%;
margin-left: 1rem;
&:first-of-type {
margin-top: 1rem;
}
}
.radio {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 14px;
width: max-content;
input[type="radio"] {
display: block;
opacity: 0;
+ label {
position: relative;
display: inline-block;
cursor: pointer;
padding-left: 1.25rem;
font-weight: 300;
&::before {
content: "";
display: inline-block;
position: absolute;
left: -($radioSize / 4) * 4;
border-radius: 50%;
border: $ui-border-width solid $text-color-70;
width: $radioSize;
height: $radioSize;
}
&::after {
content: "";
position: absolute;
display: inline-block;
left: -($radioSize / 4) * 3;
top: $radioSize / 4;
border-radius: 50%;
width: ($radioSize / 4) * 3;
height: ($radioSize / 4) * 3;
}
}
&:checked,
&:hover {
+ label::after {
background-color: $green;
}
+ label::before {
border-color: $text-color;
}
}
&:focus {
+ label::before {
outline: $ui-border-width solid Highlight;
outline-style: auto;
outline-color: -webkit-focus-ring-color;
}
}
}
}
</style>

View File

@@ -0,0 +1,79 @@
<template>
<div class="wrapper">
<h3 v-if="title" class="title">{{ title }}</h3>
<textarea :placeholder="placeholder" @input="handleInput" v-model="value" :rows="rows" />
</div>
</template>
<script>
export default {
props: {
placeholder: {
type: String,
required: false
},
title: {
type: String,
required: false
},
rows: {
type: Number,
required: false,
default: 10
},
value: {
type: String,
required: false,
default: undefined
}
},
methods: {
handleInput(event) {
if (this.value !== undefined) {
this.$emit('update:value', this.value)
} else {
this.$emit('input', this.value, event)
}
}
}
}
</script>
<style lang="scss" scoped>
@import "./src/scss/variables.scss";
.wrapper {
width: 100%;
}
.title {
margin: 0;
font-weight: 400;
text-transform: uppercase;
font-size: 14px;
color: $green;
margin-bottom: 0.5rem;
@include tablet-min {
font-size: 16px;
}
}
textarea {
width: 100%;
font-size: 14px;
padding: 0.5rem;
border: 2px solid $text-color-50;
&:focus {
border-color: $text-color;
outline: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
}
</style>