Skip to content

Commit

Permalink
Created the AppCheckbox component.
Browse files Browse the repository at this point in the history
  • Loading branch information
Utar94 committed Dec 21, 2023
1 parent aa61ecb commit 63f5b90
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 12 deletions.
15 changes: 15 additions & 0 deletions src/components/AppCheckbox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
type Booleanish = boolean | "true" | "false";

export type CheckboxOptions = {
ariaLabel?: string;
disabled?: Booleanish;
id?: string;
inline?: Booleanish;
label?: string;
modelValue?: Booleanish;
name?: string;
required?: Booleanish;
reverse?: Booleanish;
switch?: Booleanish;
value?: string;
};
62 changes: 62 additions & 0 deletions src/components/AppCheckbox.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<script setup lang="ts">
import { computed, ref } from "vue";
import { nanoid } from "nanoid";
import type { CheckboxOptions } from "./AppCheckbox";
const props = defineProps<CheckboxOptions>();
const inputRef = ref<HTMLInputElement>();
const classes = computed<string[]>(() => {
const classes = ["form-check"];
if (props.inline) {
classes.push("form-check-inline");
}
if (props.reverse) {
classes.push("form-check-reverse");
}
if (props.switch) {
classes.push("form-switch");
}
return classes;
});
const inputId = computed<string>(() => props.id ?? nanoid());
const role = computed<string | undefined>(() => (props.switch ? "switch" : undefined));
const emit = defineEmits<{
(e: "update:model-value", value: boolean): void;
}>();
function onChange(event: Event): void {
emit("update:model-value", (event.target as HTMLInputElement).checked);
}
function focus(): void {
inputRef.value?.focus();
}
defineExpose({ focus });
</script>

<template>
<div :class="classes">
<slot>
<input
:aria-label="ariaLabel"
:checked="modelValue"
class="form-check-input"
:disabled="disabled"
:id="inputId"
:name="name"
ref="inputRef"
:required="required"
:role="role"
type="checkbox"
:value="value"
@change="onChange"
/>
<slot name="label-override">
<label v-if="label" class="form-check-label" :for="inputId">{{ label }}</label>
</slot>
</slot>
</div>
</template>
6 changes: 2 additions & 4 deletions src/views/account/RecoverPasswordView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { ref } from "vue";
import { useRouter } from "vue-router";
import AppCheckbox from "@/components/AppCheckbox.vue";
import type { RecoverPasswordPayload } from "@/types/account";
import { recoverPassword } from "@/api/account";
Expand Down Expand Up @@ -34,10 +35,7 @@ function onResetPassword(): void {
<template>
<main class="container">
<h1>Recover Password</h1>
<div class="form-check form-switch mb-3">
<input class="form-check-input" id="success" role="switch" type="checkbox" v-model="success" />
<label class="form-label-check" for="success">Success</label>
</div>
<AppCheckbox class="mb-3" id="success" label="Success" switch v-model="success" />
<div v-if="success">
<div class="alert alert-success">Success!</div>
<button v-if="payload.username" type="button" class="btn btn-warning" @click="onResetPassword">
Expand Down
6 changes: 2 additions & 4 deletions src/views/account/RegisterView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { ref } from "vue";
import { useRouter } from "vue-router";
import AppCheckbox from "@/components/AppCheckbox.vue";
import type { RegisterPayload } from "@/types/account";
import { register } from "@/api/account";
Expand Down Expand Up @@ -45,10 +46,7 @@ function onEmailAddressUpdate(e: Event): void {
<template>
<main class="container">
<h1>Register</h1>
<div class="form-check form-switch mb-3">
<input class="form-check-input" id="success" role="switch" type="checkbox" v-model="success" />
<label class="form-label-check" for="success">Success</label>
</div>
<AppCheckbox class="mb-3" id="success" label="Success" switch v-model="success" />
<div v-if="success">
<div class="alert alert-success">Success!</div>
<button v-if="payload.emailAddress" type="button" class="btn btn-warning" @click="onConfirm">
Expand Down
6 changes: 2 additions & 4 deletions src/views/account/SignInView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import AppCheckbox from "@/components/AppCheckbox.vue";
import type { Actor } from "@/types/aggregate";
import type { ErrorDetail } from "@/types/api";
import type { SignInPayload } from "@/types/account";
Expand Down Expand Up @@ -53,10 +54,7 @@ async function submit(): Promise<void> {
<label class="form-label" for="password">Password</label>
<input class="form-control" id="password" placeholder="Password" type="password" v-model="payload.password" />
</div>
<div class="form-check mb-3">
<input class="form-check-input" id="remember-me" type="checkbox" v-model="payload.remember" />
<label class="form-check-label" for="remember-me">Remember Me</label>
</div>
<AppCheckbox class="mb-3" id="remember-be" label="Remember Me" v-model="payload.remember" />
<button class="btn btn-primary me-2" :disabled="loading" type="submit">
<span v-if="loading">
<span class="spinner-border spinner-border-sm" aria-hidden="true"></span>
Expand Down

0 comments on commit 63f5b90

Please sign in to comment.