2024-08-26 19:09:43 +00:00
|
|
|
<!-- eslint-disable vue/multi-word-component-names -->
|
2023-09-12 22:05:48 +00:00
|
|
|
<template>
|
2025-12-28 01:55:01 +00:00
|
|
|
<slot v-if="state === 'visible'" name="default" />
|
2023-09-12 22:05:48 +00:00
|
|
|
<span v-else>***</span>
|
2023-09-14 13:54:23 +00:00
|
|
|
<BulmaButton
|
2025-12-28 01:55:01 +00:00
|
|
|
:class="`is-small is-${record.color} ml-2`"
|
2025-12-30 02:31:53 +00:00
|
|
|
:icon="['fas', record.icon]"
|
|
|
|
|
:busy="state === 'pending'"
|
2023-09-14 13:54:23 +00:00
|
|
|
@click="on_click"
|
|
|
|
|
/>
|
2023-09-12 22:05:48 +00:00
|
|
|
</template>
|
|
|
|
|
|
2024-08-26 19:09:43 +00:00
|
|
|
<script setup lang="ts">
|
2025-12-28 01:55:01 +00:00
|
|
|
import { computed, ref } from "vue";
|
2024-08-27 00:25:42 +00:00
|
|
|
|
2023-09-14 13:54:23 +00:00
|
|
|
import BulmaButton from "./Button.vue";
|
|
|
|
|
|
2024-08-26 19:09:43 +00:00
|
|
|
const emit = defineEmits<{
|
2025-12-30 02:31:53 +00:00
|
|
|
(event: "show"): void;
|
|
|
|
|
(event: "hide"): void;
|
2024-08-26 19:09:43 +00:00
|
|
|
}>();
|
|
|
|
|
|
2025-12-30 02:31:53 +00:00
|
|
|
type State = "hidden" | "pending" | "visible";
|
2025-12-28 01:55:01 +00:00
|
|
|
const state = ref<State>("hidden");
|
2024-08-26 19:09:43 +00:00
|
|
|
|
2025-12-28 01:55:01 +00:00
|
|
|
const state_map: Record<State, { color: string; icon: string; next: State }> = {
|
2025-12-30 02:31:53 +00:00
|
|
|
hidden: { color: "primary", icon: "eye-slash", next: "pending" },
|
|
|
|
|
pending: { color: "warning", icon: "eye-slash", next: "visible" },
|
2025-12-28 01:55:01 +00:00
|
|
|
visible: { color: "danger", icon: "eye", next: "hidden" },
|
|
|
|
|
} as const;
|
|
|
|
|
const record = computed(() => state_map[state.value] ?? state_map.hidden);
|
2024-08-26 19:09:43 +00:00
|
|
|
|
2025-12-30 02:31:53 +00:00
|
|
|
let pending_timeout: number | undefined;
|
|
|
|
|
|
2025-12-28 01:55:01 +00:00
|
|
|
function on_click(): void {
|
|
|
|
|
state.value = record.value.next;
|
2024-08-26 19:09:43 +00:00
|
|
|
|
2025-12-30 02:31:53 +00:00
|
|
|
if (state.value === "hidden") {
|
|
|
|
|
emit("hide");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (state.value === "pending") {
|
|
|
|
|
pending_timeout = window.setTimeout(() => (state.value = "hidden"), 2500);
|
|
|
|
|
} else {
|
|
|
|
|
window.clearTimeout(pending_timeout);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-28 01:55:01 +00:00
|
|
|
if (state.value === "visible") {
|
2025-12-30 02:31:53 +00:00
|
|
|
emit("show");
|
2023-09-12 22:05:48 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|