summaryrefslogtreecommitdiff
path: root/src/client/components/ui/radio.vue
blob: 890ff08751986acc821a763006f464aebdc3c3b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<template>
<div
	class="novjtctn"
	:class="{ disabled, checked }"
	:aria-checked="checked"
	:aria-disabled="disabled"
	@click="toggle"
>
	<input type="radio"
		:disabled="disabled"
	>
	<span class="button">
		<span></span>
	</span>
	<span class="label"><slot></slot></span>
</div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import * as os from '@/os';

export default defineComponent({
	props: {
		modelValue: {
			required: false
		},
		value: {
			required: false
		},
		disabled: {
			type: Boolean,
			default: false
		}
	},
	computed: {
		checked(): boolean {
			return this.modelValue === this.value;
		}
	},
	methods: {
		toggle() {
			if (this.disabled) return;
			this.$emit('update:modelValue', this.value);
		}
	}
});
</script>

<style lang="scss" scoped>
.novjtctn {
	position: relative;
	display: inline-block;
	margin: 16px 32px 0 0;
	cursor: pointer;
	transition: all 0.3s;

	> * {
		user-select: none;
	}

	&.disabled {
		opacity: 0.6;

		&, * {
			cursor: not-allowed !important;
		}
	}

	&.checked {
		> .button {
			border-color: var(--accent);

			&:after {
				background-color: var(--accent);
				transform: scale(1);
				opacity: 1;
			}
		}
	}

	> input {
		position: absolute;
		width: 0;
		height: 0;
		opacity: 0;
		margin: 0;
	}

	> .button {
		position: absolute;
		width: 20px;
		height: 20px;
		background: none;
		border: solid 2px var(--inputBorder);
		border-radius: 100%;
		transition: inherit;

		&:after {
			content: '';
			display: block;
			position: absolute;
			top: 3px;
			right: 3px;
			bottom: 3px;
			left: 3px;
			border-radius: 100%;
			opacity: 0;
			transform: scale(0);
			transition: 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
		}
	}

	> .label {
		margin-left: 28px;
		display: block;
		font-size: 16px;
		line-height: 20px;
		cursor: pointer;
	}
}
</style>