@pmndrs/uikit
Version:
Build performant 3D user interfaces with Three.js and yoga.
59 lines (58 loc) • 2.77 kB
JavaScript
import { computed, signal } from '@preact/signals-core';
import { computedOrderInfo, ElementType } from './order.js';
import { setupInstancedPanel } from './panel/instanced-panel.js';
import { abortableEffect, computedBorderInset } from './utils.js';
import { createPanelMaterialConfig, } from './panel/index.js';
import { computedInheritableProperty } from './properties/index.js';
const caretBorderKeys = [
'caretBorderRightWidth',
'caretBorderTopWidth',
'caretBorderLeftWidth',
'caretBorderBottomWidth',
];
let caretMaterialConfig;
function getCaretMaterialConfig() {
caretMaterialConfig ??= createPanelMaterialConfig({
backgroundColor: 'caretColor',
backgroundOpacity: 'caretOpacity',
borderBend: 'caretBorderBend',
borderBottomLeftRadius: 'caretBorderBottomLeftRadius',
borderBottomRightRadius: 'caretBorderBottomRightRadius',
borderColor: 'caretBorderColor',
borderOpacity: 'caretBorderOpacity',
borderTopLeftRadius: 'caretBorderTopLeftRadius',
borderTopRightRadius: 'caretBorderTopRightRadius',
}, {
backgroundColor: 0x0,
backgroundOpacity: 1,
});
return caretMaterialConfig;
}
export function createCaret(propertiesSignal, matrix, caretTransformation, isVisible, parentOrderInfo, parentGroupDeps, parentClippingRect, panelGroupManager, abortSignal) {
const orderInfo = computedOrderInfo(undefined, 'zIndexOffset', ElementType.Panel, parentGroupDeps, parentOrderInfo);
const blinkingCaretTransformation = signal(undefined);
abortableEffect(() => {
const pos = caretTransformation.value;
if (pos == null) {
blinkingCaretTransformation.value = undefined;
}
blinkingCaretTransformation.value = pos;
const ref = setInterval(() => (blinkingCaretTransformation.value = blinkingCaretTransformation.peek() == null ? pos : undefined), 500);
return () => clearInterval(ref);
}, abortSignal);
const borderInset = computedBorderInset(propertiesSignal, caretBorderKeys);
const caretWidth = computedInheritableProperty(propertiesSignal, 'caretWidth', 1.5);
setupInstancedPanel(propertiesSignal, orderInfo, parentGroupDeps, panelGroupManager, matrix, computed(() => {
const height = blinkingCaretTransformation.value?.height;
if (height == null) {
return [0, 0];
}
return [caretWidth.value, height];
}), computed(() => {
const position = blinkingCaretTransformation.value?.position;
if (position == null) {
return [0, 0];
}
return [position[0] - caretWidth.value / 2, position[1]];
}), borderInset, parentClippingRect, isVisible, getCaretMaterialConfig(), abortSignal);
}