forked from profectus/Profectus
Tooltips overhaul
This commit is contained in:
parent
89861dfbd5
commit
f76d5deb6e
12 changed files with 212 additions and 146 deletions
|
@ -3,7 +3,7 @@
|
|||
<img v-if="banner" :src="banner" class="banner" :alt="title" />
|
||||
<div v-else class="title">{{ title }}</div>
|
||||
<div @click="changelog?.open()" class="version-container">
|
||||
<Tooltip display="Changelog" bottom class="version"
|
||||
<Tooltip display="Changelog" :direction="TooltipDirection.DOWN" class="version"
|
||||
><span>v{{ versionNumber }}</span></Tooltip
|
||||
>
|
||||
</div>
|
||||
|
@ -26,51 +26,56 @@
|
|||
</div>
|
||||
<div>
|
||||
<a href="https://forums.moddingtree.com/" target="_blank">
|
||||
<Tooltip display="Forums" bottom yoffset="5px">
|
||||
<Tooltip display="Forums" :direction="TooltipDirection.DOWN" yoffset="5px">
|
||||
<span class="material-icons">forum</span>
|
||||
</Tooltip>
|
||||
</a>
|
||||
</div>
|
||||
<div @click="info?.open()">
|
||||
<Tooltip display="Info" bottom class="info">
|
||||
<Tooltip display="Info" :direction="TooltipDirection.DOWN" class="info">
|
||||
<span class="material-icons">info</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div @click="savesManager?.open()">
|
||||
<Tooltip display="Saves" bottom xoffset="-20px">
|
||||
<Tooltip display="Saves" :direction="TooltipDirection.DOWN" xoffset="-20px">
|
||||
<span class="material-icons">library_books</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div @click="options?.open()">
|
||||
<Tooltip display="Options" bottom xoffset="-66px">
|
||||
<Tooltip display="Options" :direction="TooltipDirection.DOWN" xoffset="-66px">
|
||||
<span class="material-icons">settings</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="overlay-nav" v-bind="$attrs">
|
||||
<div @click="changelog?.open()" class="version-container">
|
||||
<Tooltip display="Changelog" right xoffset="25%" class="version">
|
||||
<Tooltip
|
||||
display="Changelog"
|
||||
:direction="TooltipDirection.RIGHT"
|
||||
xoffset="25%"
|
||||
class="version"
|
||||
>
|
||||
<span>v{{ versionNumber }}</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div @click="savesManager?.open()">
|
||||
<Tooltip display="Saves" right>
|
||||
<Tooltip display="Saves" :direction="TooltipDirection.RIGHT">
|
||||
<span class="material-icons">library_books</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div @click="options?.open()">
|
||||
<Tooltip display="Options" right>
|
||||
<Tooltip display="Options" :direction="TooltipDirection.RIGHT">
|
||||
<span class="material-icons">settings</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div @click="info?.open()">
|
||||
<Tooltip display="Info" right>
|
||||
<Tooltip display="Info" :direction="TooltipDirection.RIGHT">
|
||||
<span class="material-icons">info</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://forums.moddingtree.com/" target="_blank">
|
||||
<Tooltip display="Forums" right xoffset="7px">
|
||||
<Tooltip display="Forums" :direction="TooltipDirection.RIGHT" xoffset="7px">
|
||||
<span class="material-icons">forum</span>
|
||||
</Tooltip>
|
||||
</a>
|
||||
|
@ -105,7 +110,8 @@ import { ComponentPublicInstance, ref } from "vue";
|
|||
import Info from "./Info.vue";
|
||||
import Options from "./Options.vue";
|
||||
import SavesManager from "./SavesManager.vue";
|
||||
import Tooltip from "./Tooltip.vue";
|
||||
import Tooltip from "features/tooltips/Tooltip.vue";
|
||||
import { TooltipDirection } from "features/tooltips/tooltip";
|
||||
|
||||
const info = ref<ComponentPublicInstance<typeof Info> | null>(null);
|
||||
const savesManager = ref<ComponentPublicInstance<typeof SavesManager> | null>(null);
|
||||
|
|
|
@ -30,7 +30,7 @@ import { coerceComponent, render } from "util/vue";
|
|||
import { computed, ref, toRefs } from "vue";
|
||||
import Select from "./fields/Select.vue";
|
||||
import Toggle from "./fields/Toggle.vue";
|
||||
import Tooltip from "./Tooltip.vue";
|
||||
import Tooltip from "features/tooltips/Tooltip.vue";
|
||||
|
||||
const isOpen = ref(false);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { computed, toRefs, unref } from "vue";
|
||||
import Tooltip from "../Tooltip.vue";
|
||||
import Tooltip from "features/tooltips/Tooltip.vue";
|
||||
import "components/common/fields.css";
|
||||
|
||||
const _props = defineProps<{
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
import { CoercableComponent, Visibility } from "features/feature";
|
||||
import { computeOptionalComponent, processedPropType } from "util/vue";
|
||||
import { defineComponent, StyleValue, toRefs, unref } from "vue";
|
||||
import Tooltip from "components/Tooltip.vue";
|
||||
import Node from "components/Node.vue";
|
||||
import MarkNode from "components/MarkNode.vue";
|
||||
import "components/common/features.css";
|
||||
|
@ -53,8 +52,7 @@ export default defineComponent({
|
|||
},
|
||||
components: {
|
||||
Node,
|
||||
MarkNode,
|
||||
Tooltip
|
||||
MarkNode
|
||||
},
|
||||
setup(props) {
|
||||
const { display } = toRefs(props);
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
import { CoercableComponent } from "features/feature";
|
||||
import { ProcessedComputable } from "util/computed";
|
||||
|
||||
declare module "@vue/runtime-dom" {
|
||||
interface CSSProperties {
|
||||
"--xoffset"?: string;
|
||||
"--yoffset"?: string;
|
||||
}
|
||||
}
|
||||
|
||||
export interface Tooltip {
|
||||
display: ProcessedComputable<CoercableComponent>;
|
||||
top?: ProcessedComputable<boolean>;
|
||||
left?: ProcessedComputable<boolean>;
|
||||
right?: ProcessedComputable<boolean>;
|
||||
bottom?: ProcessedComputable<boolean>;
|
||||
xoffset?: ProcessedComputable<string>;
|
||||
yoffset?: ProcessedComputable<string>;
|
||||
force?: ProcessedComputable<boolean>;
|
||||
}
|
||||
|
||||
export function gatherTooltipProps(tooltip: Tooltip) {
|
||||
const { display, top, left, right, bottom, xoffset, yoffset, force } = tooltip;
|
||||
return { display, top, left, right, bottom, xoffset, yoffset, force };
|
||||
}
|
|
@ -1,20 +1,23 @@
|
|||
<template>
|
||||
<div
|
||||
class="tooltip-container"
|
||||
:class="{ shown: isShown }"
|
||||
:class="{ shown: isShown, ...unref(classes) }"
|
||||
@mouseenter="isHovered = true"
|
||||
@mouseleave="isHovered = false"
|
||||
@click="togglePinned"
|
||||
:style="unref(style)"
|
||||
>
|
||||
<slot />
|
||||
<component v-if="elementComp" :is="elementComp" />
|
||||
<transition name="fade">
|
||||
<div
|
||||
v-if="isShown"
|
||||
class="tooltip"
|
||||
:class="{
|
||||
top: unref(top),
|
||||
left: unref(left),
|
||||
right: unref(right),
|
||||
bottom: unref(bottom)
|
||||
top: unref(direction) === TooltipDirection.UP,
|
||||
left: unref(direction) === TooltipDirection.LEFT,
|
||||
right: unref(direction) === TooltipDirection.RIGHT,
|
||||
bottom: unref(direction) === TooltipDirection.DOWN
|
||||
}"
|
||||
:style="{
|
||||
'--xoffset': unref(xoffset) || '0px',
|
||||
|
@ -28,33 +31,76 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { CoercableComponent } from "features/feature";
|
||||
import { computeOptionalComponent, processedPropType, unwrapRef } from "util/vue";
|
||||
import { computed, defineComponent, ref, toRefs, unref } from "vue";
|
||||
import { CoercableComponent, jsx, StyleValue } from "features/feature";
|
||||
import { Persistent } from "game/persistence";
|
||||
import {
|
||||
coerceComponent,
|
||||
computeOptionalComponent,
|
||||
processedPropType,
|
||||
render,
|
||||
unwrapRef,
|
||||
VueFeature
|
||||
} from "util/vue";
|
||||
import {
|
||||
Component,
|
||||
computed,
|
||||
defineComponent,
|
||||
PropType,
|
||||
ref,
|
||||
shallowRef,
|
||||
toRefs,
|
||||
unref,
|
||||
watchEffect
|
||||
} from "vue";
|
||||
import { TooltipDirection } from "./tooltip";
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
display: processedPropType<CoercableComponent>(Object, String, Function),
|
||||
top: processedPropType<boolean>(Boolean),
|
||||
left: processedPropType<boolean>(Boolean),
|
||||
right: processedPropType<boolean>(Boolean),
|
||||
bottom: processedPropType<boolean>(Boolean),
|
||||
element: processedPropType<VueFeature>(Object),
|
||||
display: {
|
||||
type: processedPropType<CoercableComponent>(Object, String, Function),
|
||||
required: true
|
||||
},
|
||||
style: processedPropType<StyleValue>(Object, String, Array),
|
||||
classes: processedPropType<Record<string, boolean>>(Object),
|
||||
direction: processedPropType<TooltipDirection>(Number),
|
||||
xoffset: processedPropType<string>(String),
|
||||
yoffset: processedPropType<string>(String),
|
||||
force: processedPropType<boolean>(Boolean)
|
||||
pinned: Object as PropType<Persistent<boolean>>
|
||||
},
|
||||
setup(props) {
|
||||
const { display, force } = toRefs(props);
|
||||
const { element, display, pinned } = toRefs(props);
|
||||
|
||||
const isHovered = ref(false);
|
||||
const isShown = computed(() => (unwrapRef(force) || isHovered.value) && comp.value);
|
||||
const isShown = computed(() => (unwrapRef(pinned) || isHovered.value) && comp.value);
|
||||
const comp = computeOptionalComponent(display);
|
||||
|
||||
const elementComp = shallowRef<Component | "" | null>(null);
|
||||
watchEffect(() => {
|
||||
const currComponent = unwrapRef(element);
|
||||
elementComp.value =
|
||||
currComponent == null
|
||||
? null
|
||||
: coerceComponent(jsx(() => render(currComponent) as JSX.Element));
|
||||
});
|
||||
|
||||
function togglePinned(e: MouseEvent) {
|
||||
const isPinned = pinned as unknown as Persistent<boolean> | undefined; // Vue typing :/
|
||||
if (e.shiftKey && isPinned) {
|
||||
isPinned.value = !isPinned.value;
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
TooltipDirection,
|
||||
isHovered,
|
||||
isShown,
|
||||
comp,
|
||||
unref
|
||||
elementComp,
|
||||
unref,
|
||||
togglePinned
|
||||
};
|
||||
}
|
||||
});
|
115
src/features/tooltips/tooltip.ts
Normal file
115
src/features/tooltips/tooltip.ts
Normal file
|
@ -0,0 +1,115 @@
|
|||
import TooltipComponent from "./Tooltip.vue";
|
||||
import {
|
||||
CoercableComponent,
|
||||
Component,
|
||||
GatherProps,
|
||||
Replace,
|
||||
setDefault,
|
||||
StyleValue
|
||||
} from "features/feature";
|
||||
import {
|
||||
Computable,
|
||||
GetComputableType,
|
||||
GetComputableTypeWithDefault,
|
||||
processComputable,
|
||||
ProcessedComputable
|
||||
} from "util/computed";
|
||||
import { VueFeature } from "util/vue";
|
||||
import { readonly, ref, Ref } from "vue";
|
||||
import { persistent } from "game/persistence";
|
||||
|
||||
declare module "@vue/runtime-dom" {
|
||||
interface CSSProperties {
|
||||
"--xoffset"?: string;
|
||||
"--yoffset"?: string;
|
||||
}
|
||||
}
|
||||
|
||||
export enum TooltipDirection {
|
||||
UP,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
DOWN
|
||||
}
|
||||
|
||||
export interface TooltipOptions {
|
||||
pinnable?: boolean;
|
||||
display: Computable<CoercableComponent>;
|
||||
classes?: Computable<Record<string, boolean>>;
|
||||
style?: Computable<StyleValue>;
|
||||
direction?: Computable<TooltipDirection>;
|
||||
xoffset?: Computable<string>;
|
||||
yoffset?: Computable<string>;
|
||||
}
|
||||
|
||||
export interface BaseTooltip {
|
||||
pinned?: Ref<boolean>;
|
||||
}
|
||||
|
||||
export type Tooltip<T extends TooltipOptions> = Replace<
|
||||
T & BaseTooltip,
|
||||
{
|
||||
pinnable: T["pinnable"] extends unknown ? true : T["pinnable"];
|
||||
display: GetComputableType<T["display"]>;
|
||||
classes: GetComputableType<T["classes"]>;
|
||||
style: GetComputableType<T["style"]>;
|
||||
direction: GetComputableTypeWithDefault<T["direction"], TooltipDirection.UP>;
|
||||
xoffset: GetComputableType<T["xoffset"]>;
|
||||
yoffset: GetComputableType<T["yoffset"]>;
|
||||
}
|
||||
>;
|
||||
|
||||
export type GenericTooltip = Replace<
|
||||
Tooltip<TooltipOptions>,
|
||||
{
|
||||
pinnable: boolean;
|
||||
direction: ProcessedComputable<TooltipDirection>;
|
||||
}
|
||||
>;
|
||||
|
||||
export function addTooltip<T extends TooltipOptions>(
|
||||
element: VueFeature,
|
||||
options: T & ThisType<Tooltip<T>> & Partial<BaseTooltip>
|
||||
): Tooltip<T> {
|
||||
if (options.pinnable) {
|
||||
if ("pinned" in element) {
|
||||
console.error(
|
||||
"Cannot add pinnable tooltip to element that already has a property called 'pinned'"
|
||||
);
|
||||
options.pinnable = false;
|
||||
} else {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(element as any).pinned = options.pinned = persistent<boolean>(false);
|
||||
}
|
||||
}
|
||||
|
||||
processComputable(options as T, "display");
|
||||
processComputable(options as T, "classes");
|
||||
processComputable(options as T, "style");
|
||||
processComputable(options as T, "direction");
|
||||
setDefault(options, "direction", TooltipDirection.UP);
|
||||
processComputable(options as T, "xoffset");
|
||||
processComputable(options as T, "yoffset");
|
||||
|
||||
const elementComponent = element[Component];
|
||||
element[Component] = TooltipComponent;
|
||||
const elementGratherProps = element[GatherProps].bind(element);
|
||||
element[GatherProps] = function gatherTooltipProps(this: GenericTooltip) {
|
||||
const { display, classes, style, direction, xoffset, yoffset, pinned } = this;
|
||||
return {
|
||||
element: {
|
||||
[Component]: elementComponent,
|
||||
[GatherProps]: elementGratherProps
|
||||
},
|
||||
display,
|
||||
classes,
|
||||
style,
|
||||
direction,
|
||||
xoffset,
|
||||
yoffset,
|
||||
pinned
|
||||
};
|
||||
}.bind(options as GenericTooltip);
|
||||
|
||||
return options as unknown as Tooltip<T>;
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
v-for="(node, nodeIndex) in row"
|
||||
:key="nodeIndex"
|
||||
v-bind="gatherNodeProps(node)"
|
||||
:force-tooltip="node.forceTooltip"
|
||||
/>
|
||||
</span>
|
||||
<span class="left-side-nodes" v-if="unref(leftSideNodes)">
|
||||
|
@ -12,7 +11,6 @@
|
|||
v-for="(node, nodeIndex) in unref(leftSideNodes)"
|
||||
:key="nodeIndex"
|
||||
v-bind="gatherNodeProps(node)"
|
||||
:force-tooltip="node.forceTooltip"
|
||||
small
|
||||
/>
|
||||
</span>
|
||||
|
@ -21,7 +19,6 @@
|
|||
v-for="(node, nodeIndex) in unref(rightSideNodes)"
|
||||
:key="nodeIndex"
|
||||
v-bind="gatherNodeProps(node)"
|
||||
:force-tooltip="node.forceTooltip"
|
||||
small
|
||||
/>
|
||||
</span>
|
||||
|
@ -54,12 +51,10 @@ export default defineComponent({
|
|||
visibility,
|
||||
style,
|
||||
classes,
|
||||
tooltip,
|
||||
onClick,
|
||||
onHold,
|
||||
color,
|
||||
glowColor,
|
||||
forceTooltip,
|
||||
canClick,
|
||||
mark,
|
||||
id
|
||||
|
@ -69,12 +64,10 @@ export default defineComponent({
|
|||
visibility,
|
||||
style,
|
||||
classes,
|
||||
tooltip,
|
||||
onClick,
|
||||
onHold,
|
||||
color,
|
||||
glowColor,
|
||||
forceTooltip,
|
||||
canClick,
|
||||
mark,
|
||||
id
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
<template>
|
||||
<Tooltip
|
||||
<div
|
||||
v-if="unref(visibility) !== Visibility.None"
|
||||
v-bind="tooltipToBind && gatherTooltipProps(tooltipToBind)"
|
||||
:display="tooltipDisplay"
|
||||
:force="forceTooltip"
|
||||
:style="{ visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined }"
|
||||
:class="{
|
||||
treeNode: true,
|
||||
|
@ -13,7 +10,7 @@
|
|||
}"
|
||||
>
|
||||
<div
|
||||
@click="click"
|
||||
@click="onClick"
|
||||
@mousedown="start"
|
||||
@mouseleave="stop"
|
||||
@mouseup="stop"
|
||||
|
@ -34,33 +31,20 @@
|
|||
</div>
|
||||
<MarkNode :mark="unref(mark)" />
|
||||
<Node :id="id" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Node from "components/Node.vue";
|
||||
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";
|
||||
import {
|
||||
computeOptionalComponent,
|
||||
isCoercableComponent,
|
||||
processedPropType,
|
||||
setupHoldToClick,
|
||||
unwrapRef
|
||||
setupHoldToClick
|
||||
} from "util/vue";
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
PropType,
|
||||
Ref,
|
||||
shallowRef,
|
||||
toRefs,
|
||||
unref,
|
||||
watchEffect
|
||||
} from "vue";
|
||||
import { defineComponent, PropType, toRefs, unref } from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
|
@ -71,15 +55,10 @@ export default defineComponent({
|
|||
},
|
||||
style: processedPropType<StyleValue>(String, Object, Array),
|
||||
classes: processedPropType<Record<string, boolean>>(Object),
|
||||
tooltip: processedPropType<CoercableComponent | Tooltip>(Object, String, Function),
|
||||
onClick: Function as PropType<(e?: MouseEvent | TouchEvent) => void>,
|
||||
onHold: Function as PropType<VoidFunction>,
|
||||
color: processedPropType<string>(String),
|
||||
glowColor: processedPropType<string>(String),
|
||||
forceTooltip: {
|
||||
type: Object as PropType<Ref<boolean>>,
|
||||
required: true
|
||||
},
|
||||
canClick: {
|
||||
type: processedPropType<boolean>(Boolean),
|
||||
required: true
|
||||
|
@ -92,55 +71,22 @@ export default defineComponent({
|
|||
small: processedPropType<boolean>(Boolean)
|
||||
},
|
||||
components: {
|
||||
Tooltip: TooltipVue,
|
||||
MarkNode,
|
||||
Node
|
||||
},
|
||||
setup(props) {
|
||||
const { tooltip, forceTooltip, onClick, onHold, display } = toRefs(props);
|
||||
|
||||
function click(e: MouseEvent) {
|
||||
if (e.shiftKey && tooltip) {
|
||||
forceTooltip.value = !forceTooltip.value;
|
||||
} else {
|
||||
unref(onClick)?.();
|
||||
}
|
||||
}
|
||||
const { onClick, onHold, display } = toRefs(props);
|
||||
|
||||
const comp = computeOptionalComponent(display);
|
||||
const tooltipDisplay = shallowRef<ProcessedComputable<CoercableComponent> | undefined>(
|
||||
undefined
|
||||
);
|
||||
watchEffect(() => {
|
||||
const currTooltip = unwrapRef(tooltip);
|
||||
|
||||
if (typeof currTooltip === "object" && !isCoercableComponent(currTooltip)) {
|
||||
tooltipDisplay.value = currTooltip.display;
|
||||
return;
|
||||
}
|
||||
tooltipDisplay.value = currTooltip;
|
||||
});
|
||||
const tooltipToBind = computed(() => {
|
||||
const currTooltip = unwrapRef(tooltip);
|
||||
|
||||
if (typeof currTooltip === "object" && !isCoercableComponent(currTooltip)) {
|
||||
return currTooltip;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
const { start, stop } = setupHoldToClick(onClick, onHold);
|
||||
|
||||
return {
|
||||
click,
|
||||
start,
|
||||
stop,
|
||||
comp,
|
||||
tooltipDisplay,
|
||||
tooltipToBind,
|
||||
unref,
|
||||
Visibility,
|
||||
gatherTooltipProps,
|
||||
isCoercableComponent
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,9 +12,7 @@ import {
|
|||
import { Link } from "features/links/links";
|
||||
import { GenericReset } from "features/reset";
|
||||
import { displayResource, Resource } from "features/resources/resource";
|
||||
import { Tooltip } from "features/tooltip";
|
||||
import TreeComponent from "features/trees/Tree.vue";
|
||||
import { deletePersistent, persistent } from "game/persistence";
|
||||
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
|
||||
import {
|
||||
Computable,
|
||||
|
@ -35,7 +33,6 @@ export interface TreeNodeOptions {
|
|||
canClick?: Computable<boolean>;
|
||||
color?: Computable<string>;
|
||||
display?: Computable<CoercableComponent>;
|
||||
tooltip?: Computable<string | Tooltip>;
|
||||
glowColor?: Computable<string>;
|
||||
classes?: Computable<Record<string, boolean>>;
|
||||
style?: Computable<StyleValue>;
|
||||
|
@ -47,7 +44,6 @@ export interface TreeNodeOptions {
|
|||
|
||||
export interface BaseTreeNode {
|
||||
id: string;
|
||||
forceTooltip: Ref<boolean>;
|
||||
type: typeof TreeNodeType;
|
||||
}
|
||||
|
||||
|
@ -62,7 +58,6 @@ export type TreeNode<T extends TreeNodeOptions> = Replace<
|
|||
classes: GetComputableType<T["classes"]>;
|
||||
style: GetComputableType<T["style"]>;
|
||||
mark: GetComputableType<T["mark"]>;
|
||||
tooltip: GetComputableType<T["tooltip"]>;
|
||||
}
|
||||
>;
|
||||
|
||||
|
@ -77,27 +72,17 @@ export type GenericTreeNode = Replace<
|
|||
export function createTreeNode<T extends TreeNodeOptions>(
|
||||
optionsFunc: OptionsFunc<T, TreeNode<T>, BaseTreeNode>
|
||||
): TreeNode<T> {
|
||||
const forceTooltip = persistent(false);
|
||||
return createLazyProxy(() => {
|
||||
const treeNode = optionsFunc();
|
||||
treeNode.id = getUniqueID("treeNode-");
|
||||
treeNode.type = TreeNodeType;
|
||||
|
||||
if (treeNode.tooltip) {
|
||||
treeNode.forceTooltip = forceTooltip;
|
||||
} else {
|
||||
// If we don't have a tooltip, no point in making this persistent
|
||||
treeNode.forceTooltip = ref(false);
|
||||
deletePersistent(forceTooltip);
|
||||
}
|
||||
|
||||
processComputable(treeNode as T, "visibility");
|
||||
setDefault(treeNode, "visibility", Visibility.Visible);
|
||||
processComputable(treeNode as T, "canClick");
|
||||
setDefault(treeNode, "canClick", true);
|
||||
processComputable(treeNode as T, "color");
|
||||
processComputable(treeNode as T, "display");
|
||||
processComputable(treeNode as T, "tooltip");
|
||||
processComputable(treeNode as T, "glowColor");
|
||||
processComputable(treeNode as T, "classes");
|
||||
processComputable(treeNode as T, "style");
|
||||
|
|
|
@ -40,8 +40,10 @@ export function createLazyProxy<T extends object, S>(
|
|||
return (calculateObj() as any)[key];
|
||||
},
|
||||
set(target, key, value) {
|
||||
console.error("Layers and features are shallow readonly", key, value);
|
||||
return false;
|
||||
// TODO give warning about this? It should only be done with caution
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(calculateObj() as any)[key] = value;
|
||||
return true;
|
||||
},
|
||||
has(target, key) {
|
||||
if (key === ProxyState) {
|
||||
|
|
|
@ -164,8 +164,8 @@ export function getFirstFeature<T extends { visibility: ProcessedComputable<Visi
|
|||
export function computeComponent(
|
||||
component: Ref<ProcessedComputable<CoercableComponent>>,
|
||||
defaultWrapper = "div"
|
||||
): ShallowRef<Component | JSXFunction | ""> {
|
||||
const comp = shallowRef<Component | JSXFunction | "">();
|
||||
): ShallowRef<Component | ""> {
|
||||
const comp = shallowRef<Component | "">();
|
||||
watchEffect(() => {
|
||||
comp.value = coerceComponent(unwrapRef(component), defaultWrapper);
|
||||
});
|
||||
|
@ -174,8 +174,8 @@ export function computeComponent(
|
|||
export function computeOptionalComponent(
|
||||
component: Ref<ProcessedComputable<CoercableComponent | undefined> | undefined>,
|
||||
defaultWrapper = "div"
|
||||
): ShallowRef<Component | JSXFunction | "" | null> {
|
||||
const comp = shallowRef<Component | JSXFunction | "" | null>(null);
|
||||
): ShallowRef<Component | "" | null> {
|
||||
const comp = shallowRef<Component | "" | null>(null);
|
||||
watchEffect(() => {
|
||||
const currComponent = unwrapRef(component);
|
||||
comp.value = currComponent == null ? null : coerceComponent(currComponent, defaultWrapper);
|
||||
|
|
Loading…
Reference in a new issue