This commit is contained in:
Christian Fehmer 2026-01-08 18:13:27 +01:00
parent a297539ba2
commit 3def579129
No known key found for this signature in database
GPG key ID: A567394D76EBDD7C
4 changed files with 56 additions and 43 deletions

View file

@ -1,52 +1,13 @@
import { Accessor, createEffect, JSXElement, onMount } from "solid-js";
import { ElementWithUtils } from "../utils/dom";
import { isFocused } from "./focus";
import { Accessor, JSXElement } from "solid-js";
import { VisibleDirectiveProps } from "../types/solid-directives";
export function LiveCounter(props: {
value: Accessor<string>;
visible: Accessor<{
value: boolean;
withAnimation: boolean;
}>;
visible?: VisibleDirectiveProps;
class?: string;
}): JSXElement {
// oxlint-disable-next-line no-unassigned-vars
let divRef: HTMLDivElement | undefined;
let divUtil: ElementWithUtils<HTMLDivElement> | undefined;
onMount(() => {
if (divRef) {
divUtil = new ElementWithUtils(divRef);
}
});
createEffect(() => {
if (divUtil === undefined) return;
const visibleState = props.visible();
const focusState = isFocused();
if (visibleState.value && focusState) {
if (visibleState.withAnimation) {
divUtil.animate({
opacity: [0, 1],
duration: 125,
});
} else {
divUtil.setStyle({ opacity: "1" });
}
} else {
if (visibleState.withAnimation) {
divUtil.animate({
opacity: [1, 0],
duration: 125,
});
} else {
divUtil.setStyle({ opacity: "0" });
}
}
});
return (
<div ref={divRef} class={`${props.class}`}>
<div class={`${props.class}`} use:visible={props.visible}>
{props.value()}
</div>
);

View file

@ -0,0 +1,15 @@
import type { Accessor } from "solid-js";
export type VisibleDirectiveProps = Accessor<{
value: boolean;
withAnimation: boolean;
}>;
declare module "solid-js" {
namespace JSX {
// oxlint-disable-next-line consistent-type-definitions
interface Directives {
visible: VisibleDirectiveProps;
}
}
}

View file

@ -0,0 +1,36 @@
import { createEffect } from "solid-js";
import { ElementWithUtils } from "./dom";
import { applyReducedMotion } from "./misc";
import { isFocused } from "../test/focus";
import { VisibleDirectiveProps } from "../types/solid-directives";
export function visible(
el: HTMLElement,
isVisible: VisibleDirectiveProps,
): void {
const divUtil = new ElementWithUtils(el);
createEffect(() => {
const visibleState = isVisible();
const focusState = isFocused();
if (visibleState.value && focusState) {
if (visibleState.withAnimation) {
divUtil.animate({
opacity: [0, 1],
duration: applyReducedMotion(1250),
});
} else {
divUtil.setStyle({ opacity: "1" });
}
} else {
if (visibleState.withAnimation) {
divUtil.animate({
opacity: [1, 0],
duration: applyReducedMotion(1250),
});
} else {
divUtil.setStyle({ opacity: "0" });
}
}
});
}

View file

@ -21,6 +21,7 @@
"./src/**/*.ts",
"./src/**/*.tsx",
"./scripts/**/*.ts",
"./src/**/*.d.ts",
"vite-plugins/**/*.ts",
"vite.config.ts"
],