2022-01-13 22:25:47 -06:00
|
|
|
<template>
|
|
|
|
<Tooltip
|
2022-01-24 22:25:34 -06:00
|
|
|
v-if="unref(visibility) !== Visibility.None"
|
2022-02-27 13:49:34 -06:00
|
|
|
v-bind="tooltipToBind && gatherTooltipProps(tooltipToBind)"
|
2022-01-24 22:25:34 -06:00
|
|
|
:display="tooltipDisplay"
|
2022-01-13 22:25:47 -06:00
|
|
|
:force="forceTooltip"
|
2022-02-27 13:49:34 -06:00
|
|
|
:style="{ visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined }"
|
2022-01-13 22:25:47 -06:00
|
|
|
:class="{
|
|
|
|
treeNode: true,
|
2022-01-24 22:25:34 -06:00
|
|
|
can: unref(canClick),
|
|
|
|
small: unref(small),
|
|
|
|
...unref(classes)
|
2022-01-13 22:25:47 -06:00
|
|
|
}"
|
|
|
|
>
|
|
|
|
<button
|
|
|
|
@click="click"
|
|
|
|
@mousedown="start"
|
|
|
|
@mouseleave="stop"
|
|
|
|
@mouseup="stop"
|
|
|
|
@touchstart="start"
|
|
|
|
@touchend="stop"
|
|
|
|
@touchcancel="stop"
|
|
|
|
:style="[
|
|
|
|
{
|
2022-01-24 22:25:34 -06:00
|
|
|
backgroundColor: unref(color),
|
|
|
|
boxShadow: `-4px -4px 4px rgba(0, 0, 0, 0.25) inset, 0 0 20px ${unref(
|
|
|
|
glowColor
|
|
|
|
)}`
|
2022-01-13 22:25:47 -06:00
|
|
|
},
|
2022-01-24 22:25:34 -06:00
|
|
|
unref(style) ?? []
|
2022-01-13 22:25:47 -06:00
|
|
|
]"
|
|
|
|
>
|
2022-02-27 13:49:34 -06:00
|
|
|
<component :is="unref(comp)" />
|
2022-01-13 22:25:47 -06:00
|
|
|
</button>
|
2022-01-24 22:25:34 -06:00
|
|
|
<MarkNode :mark="unref(mark)" />
|
2022-03-20 13:57:45 -05:00
|
|
|
<Node :id="id" />
|
2022-01-13 22:25:47 -06:00
|
|
|
</Tooltip>
|
|
|
|
</template>
|
|
|
|
|
2022-01-24 22:25:34 -06:00
|
|
|
<script lang="ts">
|
2022-03-20 13:57:45 -05:00
|
|
|
import Node from "components/Node.vue";
|
2022-03-03 21:39:48 -06:00
|
|
|
import MarkNode from "components/MarkNode.vue";
|
|
|
|
import TooltipVue from "components/Tooltip.vue";
|
|
|
|
import { CoercableComponent, StyleValue, Visibility } from "features/feature";
|
|
|
|
import { gatherTooltipProps, Tooltip } from "features/tooltip";
|
|
|
|
import { ProcessedComputable } from "util/computed";
|
2022-01-24 22:25:34 -06:00
|
|
|
import {
|
|
|
|
computeOptionalComponent,
|
|
|
|
isCoercableComponent,
|
2022-02-27 13:49:34 -06:00
|
|
|
processedPropType,
|
2022-01-24 22:25:34 -06:00
|
|
|
setupHoldToClick,
|
|
|
|
unwrapRef
|
2022-03-03 21:39:48 -06:00
|
|
|
} from "util/vue";
|
2022-02-27 13:49:34 -06:00
|
|
|
import {
|
|
|
|
computed,
|
|
|
|
defineComponent,
|
|
|
|
PropType,
|
|
|
|
Ref,
|
|
|
|
shallowRef,
|
|
|
|
toRefs,
|
|
|
|
unref,
|
|
|
|
watchEffect
|
|
|
|
} from "vue";
|
2022-01-24 22:25:34 -06:00
|
|
|
|
|
|
|
export default defineComponent({
|
|
|
|
props: {
|
2022-02-27 13:49:34 -06:00
|
|
|
display: processedPropType<CoercableComponent>(Object, String, Function),
|
2022-01-24 22:25:34 -06:00
|
|
|
visibility: {
|
2022-02-27 13:49:34 -06:00
|
|
|
type: processedPropType<Visibility>(Number),
|
2022-01-24 22:25:34 -06:00
|
|
|
required: true
|
|
|
|
},
|
2022-02-27 13:49:34 -06:00
|
|
|
style: processedPropType<StyleValue>(String, Object, Array),
|
|
|
|
classes: processedPropType<Record<string, boolean>>(Object),
|
|
|
|
tooltip: processedPropType<CoercableComponent | Tooltip>(Object, String, Function),
|
2022-03-27 00:14:35 -05:00
|
|
|
onClick: Function as PropType<(e?: MouseEvent | TouchEvent) => void>,
|
2022-01-24 22:25:34 -06:00
|
|
|
onHold: Function as PropType<VoidFunction>,
|
2022-02-27 13:49:34 -06:00
|
|
|
color: processedPropType<string>(String),
|
|
|
|
glowColor: processedPropType<string>(String),
|
2022-01-24 22:25:34 -06:00
|
|
|
forceTooltip: {
|
|
|
|
type: Object as PropType<Ref<boolean>>,
|
|
|
|
required: true
|
|
|
|
},
|
|
|
|
canClick: {
|
2022-02-27 13:49:34 -06:00
|
|
|
type: processedPropType<boolean>(Boolean),
|
2022-01-24 22:25:34 -06:00
|
|
|
required: true
|
|
|
|
},
|
2022-02-27 13:49:34 -06:00
|
|
|
mark: processedPropType<boolean | string>(Boolean, String),
|
2022-01-24 22:25:34 -06:00
|
|
|
id: {
|
2022-02-27 13:49:34 -06:00
|
|
|
type: String,
|
2022-01-24 22:25:34 -06:00
|
|
|
required: true
|
|
|
|
},
|
2022-02-27 13:49:34 -06:00
|
|
|
small: processedPropType<boolean>(Boolean)
|
|
|
|
},
|
|
|
|
components: {
|
|
|
|
Tooltip: TooltipVue,
|
|
|
|
MarkNode,
|
2022-03-20 13:57:45 -05:00
|
|
|
Node
|
2022-01-24 22:25:34 -06:00
|
|
|
},
|
|
|
|
setup(props) {
|
|
|
|
const { tooltip, forceTooltip, onClick, onHold, display } = toRefs(props);
|
2022-01-13 22:25:47 -06:00
|
|
|
|
2022-01-24 22:25:34 -06:00
|
|
|
function click(e: MouseEvent) {
|
|
|
|
if (e.shiftKey && tooltip) {
|
|
|
|
forceTooltip.value = !forceTooltip.value;
|
|
|
|
} else {
|
|
|
|
unref(onClick)?.();
|
|
|
|
}
|
2022-01-13 22:25:47 -06:00
|
|
|
}
|
|
|
|
|
2022-02-27 13:49:34 -06:00
|
|
|
const comp = computeOptionalComponent(display);
|
|
|
|
const tooltipDisplay = shallowRef<ProcessedComputable<CoercableComponent> | undefined>(
|
|
|
|
undefined
|
|
|
|
);
|
|
|
|
watchEffect(() => {
|
2022-01-24 22:25:34 -06:00
|
|
|
const currTooltip = unwrapRef(tooltip);
|
2022-01-13 22:25:47 -06:00
|
|
|
|
2022-01-24 22:25:34 -06:00
|
|
|
if (typeof currTooltip === "object" && !isCoercableComponent(currTooltip)) {
|
2022-02-27 13:49:34 -06:00
|
|
|
tooltipDisplay.value = currTooltip.display;
|
|
|
|
return;
|
2022-01-24 22:25:34 -06:00
|
|
|
}
|
2022-02-27 13:49:34 -06:00
|
|
|
tooltipDisplay.value = currTooltip;
|
2022-01-24 22:25:34 -06:00
|
|
|
});
|
|
|
|
const tooltipToBind = computed(() => {
|
|
|
|
const currTooltip = unwrapRef(tooltip);
|
|
|
|
|
|
|
|
if (typeof currTooltip === "object" && !isCoercableComponent(currTooltip)) {
|
|
|
|
return currTooltip;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
});
|
|
|
|
|
|
|
|
const { start, stop } = setupHoldToClick(onClick, onHold);
|
2022-01-13 22:25:47 -06:00
|
|
|
|
2022-01-24 22:25:34 -06:00
|
|
|
return {
|
|
|
|
click,
|
|
|
|
start,
|
|
|
|
stop,
|
2022-02-27 13:49:34 -06:00
|
|
|
comp,
|
2022-01-24 22:25:34 -06:00
|
|
|
tooltipDisplay,
|
|
|
|
tooltipToBind,
|
|
|
|
unref,
|
|
|
|
Visibility,
|
2022-02-27 13:49:34 -06:00
|
|
|
gatherTooltipProps,
|
2022-01-24 22:25:34 -06:00
|
|
|
isCoercableComponent
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
2022-01-13 22:25:47 -06:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
.treeNode {
|
|
|
|
height: 100px;
|
|
|
|
width: 100px;
|
|
|
|
border-radius: 50%;
|
|
|
|
padding: 0;
|
|
|
|
margin: 0 10px 0 10px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.treeNode button {
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
border: 2px solid rgba(0, 0, 0, 0.125);
|
|
|
|
border-radius: inherit;
|
|
|
|
font-size: 40px;
|
|
|
|
color: rgba(0, 0, 0, 0.5);
|
|
|
|
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
|
|
|
|
box-shadow: -4px -4px 4px rgba(0, 0, 0, 0.25) inset, 0px 0px 20px var(--background);
|
|
|
|
text-transform: capitalize;
|
|
|
|
}
|
|
|
|
|
|
|
|
.treeNode.small {
|
|
|
|
height: 60px;
|
|
|
|
width: 60px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.treeNode.small button {
|
|
|
|
font-size: 30px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.ghost {
|
|
|
|
visibility: hidden;
|
|
|
|
pointer-events: none;
|
|
|
|
}
|
|
|
|
</style>
|