From 0ac943de909fb5a685a608d7894248cdd3a9e129 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Fri, 31 Oct 2025 09:45:57 -0500 Subject: wip: desktop work --- packages/ui/src/components/index.ts | 1 + packages/ui/src/components/typewriter.css | 14 ++++++++ packages/ui/src/components/typewriter.tsx | 54 +++++++++++++++++++++++++++++++ packages/ui/src/styles/index.css | 1 + 4 files changed, 70 insertions(+) create mode 100644 packages/ui/src/components/typewriter.css create mode 100644 packages/ui/src/components/typewriter.tsx (limited to 'packages/ui') diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index 115e5f14f..499f2e27f 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -20,6 +20,7 @@ export * from "./select-dialog" export * from "./tabs" export * from "./basic-tool" export * from "./tooltip" +export * from "./typewriter" export * from "../context/helper" export * from "../context/shiki" diff --git a/packages/ui/src/components/typewriter.css b/packages/ui/src/components/typewriter.css new file mode 100644 index 000000000..e978312a9 --- /dev/null +++ b/packages/ui/src/components/typewriter.css @@ -0,0 +1,14 @@ +@keyframes blink { + 0%, + 50% { + opacity: 1; + } + 51%, + 100% { + opacity: 0; + } +} + +.blinking-cursor { + animation: blink 1s step-end infinite; +} diff --git a/packages/ui/src/components/typewriter.tsx b/packages/ui/src/components/typewriter.tsx new file mode 100644 index 000000000..9adb267ad --- /dev/null +++ b/packages/ui/src/components/typewriter.tsx @@ -0,0 +1,54 @@ +import { createEffect, Show, type ValidComponent } from "solid-js" +import { createStore } from "solid-js/store" +import { Dynamic } from "solid-js/web" + +export const Typewriter = (props: { + text?: string + class?: string + as?: T +}) => { + const [store, setStore] = createStore({ + typing: false, + displayed: "", + cursor: true, + }) + + createEffect(() => { + const text = props.text + if (!text) return + + let i = 0 + setStore("typing", true) + setStore("displayed", "") + setStore("cursor", true) + + const getTypingDelay = () => { + const random = Math.random() + if (random < 0.05) return 150 + Math.random() * 100 + if (random < 0.15) return 80 + Math.random() * 60 + return 30 + Math.random() * 50 + } + + const type = () => { + if (i < text.length) { + setStore("displayed", text.slice(0, i + 1)) + i++ + setTimeout(type, getTypingDelay()) + } else { + setStore("typing", false) + setTimeout(() => setStore("cursor", false), 2000) + } + } + + setTimeout(type, 200) + }) + + return ( + + {store.displayed} + + + + + ) +} diff --git a/packages/ui/src/styles/index.css b/packages/ui/src/styles/index.css index cea5a082d..146d957e2 100644 --- a/packages/ui/src/styles/index.css +++ b/packages/ui/src/styles/index.css @@ -25,5 +25,6 @@ @import "../components/select-dialog.css" layer(components); @import "../components/tabs.css" layer(components); @import "../components/tooltip.css" layer(components); +@import "../components/typewriter.css" layer(components); @import "./utilities.css" layer(utilities); -- cgit v1.2.3