Profectus/src/components/features/Clickable.vue

105 lines
3 KiB
Vue
Raw Normal View History

2021-06-11 23:38:16 -05:00
<template>
2022-01-13 22:25:47 -06:00
<div v-if="visibility !== Visibility.None" v-show="visibility === Visibility.Visible">
<button
:style="style"
2022-01-13 22:25:47 -06:00
@click="onClick"
@mousedown="start"
@mouseleave="stop"
@mouseup="stop"
@touchstart="start"
@touchend="stop"
@touchcancel="stop"
2022-01-13 22:25:47 -06:00
:disabled="!canClick"
:class="{
feature: true,
clickable: true,
2022-01-24 22:25:34 -06:00
can: canClick,
2022-01-13 22:25:47 -06:00
locked: !canClick,
small,
...classes
}"
>
2022-01-13 22:25:47 -06:00
<component v-if="component" :is="component" />
<MarkNode :mark="mark" />
<LinkNode :id="id" />
</button>
</div>
2021-06-11 23:38:16 -05:00
</template>
2022-01-24 22:25:34 -06:00
<script lang="tsx">
2022-01-13 22:25:47 -06:00
import { GenericClickable } from "@/features/clickable";
2022-01-24 22:25:34 -06:00
import { StyleValue, Visibility } from "@/features/feature";
2022-01-13 22:25:47 -06:00
import { coerceComponent, isCoercableComponent, setupHoldToClick } from "@/util/vue";
2022-01-24 22:25:34 -06:00
import { computed, defineComponent, PropType, toRefs, unref, UnwrapRef } from "vue";
2022-01-13 22:25:47 -06:00
import LinkNode from "../system/LinkNode.vue";
import MarkNode from "./MarkNode.vue";
2022-01-24 22:25:34 -06:00
export default defineComponent({
props: {
display: {
type: Object as PropType<UnwrapRef<GenericClickable["display"]>>,
required: true
},
visibility: {
type: Object as PropType<Visibility>,
required: true
},
style: Object as PropType<StyleValue>,
classes: Object as PropType<Record<string, boolean>>,
onClick: Function as PropType<VoidFunction>,
onHold: Function as PropType<VoidFunction>,
canClick: {
type: Boolean,
required: true
},
small: Boolean,
mark: [Boolean, String],
id: {
type: String,
required: true
}
},
setup(props) {
const { display, onClick, onHold } = toRefs(props);
2021-06-11 23:38:16 -05:00
2022-01-24 22:25:34 -06:00
const component = computed(() => {
const currDisplay = unref(display);
if (currDisplay == null) {
return null;
}
if (isCoercableComponent(currDisplay)) {
return coerceComponent(currDisplay);
}
return (
<span>
<div v-if={currDisplay.title}>
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
<component v-is={coerceComponent(currDisplay.title!, "h2")} />
</div>
<component v-is={coerceComponent(currDisplay.description, "div")} />
</span>
);
});
const { start, stop } = setupHoldToClick(onClick, onHold);
return {
start,
stop,
component,
LinkNode,
MarkNode,
Visibility
};
}
});
2021-06-11 23:38:16 -05:00
</script>
<style scoped>
2021-06-24 22:15:10 -05:00
.clickable {
min-height: 120px;
width: 120px;
font-size: 10px;
}
2021-06-11 23:38:16 -05:00
</style>