From 1f848dda647fc968a6a64094c6f21f029f88e2ee Mon Sep 17 00:00:00 2001 From: GreyElaina Date: Wed, 7 Jan 2026 09:17:28 +0800 Subject: [PATCH 1/7] feat(vue): comprehensive update with devtools, tests, Portal, and examples Devtools: - Add Vue DevTools integration with custom inspector for renderables - Add highlight overlay, timeline tracking, and element picker - Support auto-refresh, visibility toggle, and element focusing Components & Composables: - Add Portal component for rendering outside parent hierarchy - Add usePaste, useSelectionHandler, useTimeline composables - Update useCliRenderer and useKeyboard Renderer: - Improve createElement, patchProp for better Vue 3 compatibility - Add support for onKeyDown, onContentChange, onCursorChange events - Handle TextNode rendering with nodeRenderable Tests: - Add comprehensive test suite (control-flow, events, layout, portal, text-nodes) - Add test-utils.ts for testing infrastructure Examples: - Add Animation, Code, Diff, LineNumber, Textarea examples - Update existing examples for new patterns --- packages/vue/example/ASCII.vue | 6 +- packages/vue/example/Animation.vue | 182 +++ packages/vue/example/App.vue | 22 +- packages/vue/example/Code.vue | 74 ++ packages/vue/example/Counter.vue | 13 +- packages/vue/example/Diff.vue | 107 ++ packages/vue/example/LineNumber.vue | 144 +++ packages/vue/example/LoginForm.vue | 17 +- packages/vue/example/Textarea.vue | 126 ++ packages/vue/index.ts | 87 +- packages/vue/package.json | 18 +- packages/vue/src/cli-renderer-ref.ts | 14 - packages/vue/src/components/Portal.ts | 121 ++ packages/vue/src/composables/index.ts | 5 +- .../vue/src/composables/useCliRenderer.ts | 4 +- packages/vue/src/composables/useKeyboard.ts | 36 +- packages/vue/src/composables/usePaste.ts | 16 + .../src/composables/useSelectionHandler.ts | 15 + packages/vue/src/composables/useTimeline.ts | 20 + packages/vue/src/devtools/connect.ts | 154 +++ packages/vue/src/devtools/highlight.ts | 125 ++ packages/vue/src/devtools/index.ts | 265 +++++ packages/vue/src/devtools/inspector.ts | 250 ++++ packages/vue/src/devtools/theme.ts | 23 + packages/vue/src/devtools/timeline.ts | 92 ++ packages/vue/src/elements.ts | 100 +- packages/vue/src/noOps.ts | 207 +++- packages/vue/src/nodes.ts | 21 +- packages/vue/src/renderer.ts | 104 +- packages/vue/src/test-utils.ts | 63 + packages/vue/tests/control-flow.test.ts | 1016 +++++++++++++++++ packages/vue/tests/devtools-hook.test.ts | 106 ++ packages/vue/tests/events.test.ts | 757 ++++++++++++ packages/vue/tests/layout.test.ts | 429 +++++++ packages/vue/tests/portal.test.ts | 151 +++ packages/vue/tests/text-nodes.test.ts | 81 ++ packages/vue/tsconfig.json | 2 +- packages/vue/tsconfig.typecheck.json | 12 + packages/vue/types/opentui.d.ts | 93 +- 39 files changed, 4977 insertions(+), 101 deletions(-) create mode 100644 packages/vue/example/Animation.vue create mode 100644 packages/vue/example/Code.vue create mode 100644 packages/vue/example/Diff.vue create mode 100644 packages/vue/example/LineNumber.vue create mode 100644 packages/vue/example/Textarea.vue delete mode 100644 packages/vue/src/cli-renderer-ref.ts create mode 100644 packages/vue/src/components/Portal.ts create mode 100644 packages/vue/src/composables/usePaste.ts create mode 100644 packages/vue/src/composables/useSelectionHandler.ts create mode 100644 packages/vue/src/composables/useTimeline.ts create mode 100644 packages/vue/src/devtools/connect.ts create mode 100644 packages/vue/src/devtools/highlight.ts create mode 100644 packages/vue/src/devtools/index.ts create mode 100644 packages/vue/src/devtools/inspector.ts create mode 100644 packages/vue/src/devtools/theme.ts create mode 100644 packages/vue/src/devtools/timeline.ts create mode 100644 packages/vue/src/test-utils.ts create mode 100644 packages/vue/tests/control-flow.test.ts create mode 100644 packages/vue/tests/devtools-hook.test.ts create mode 100644 packages/vue/tests/events.test.ts create mode 100644 packages/vue/tests/layout.test.ts create mode 100644 packages/vue/tests/portal.test.ts create mode 100644 packages/vue/tests/text-nodes.test.ts create mode 100644 packages/vue/tsconfig.typecheck.json diff --git a/packages/vue/example/ASCII.vue b/packages/vue/example/ASCII.vue index 9be77dd30..6aefe6328 100644 --- a/packages/vue/example/ASCII.vue +++ b/packages/vue/example/ASCII.vue @@ -1,5 +1,6 @@ + + diff --git a/packages/vue/example/App.vue b/packages/vue/example/App.vue index bd2fbf609..1bd850f03 100644 --- a/packages/vue/example/App.vue +++ b/packages/vue/example/App.vue @@ -5,18 +5,28 @@ import Counter from "./Counter.vue" import StyledText from "./Styled-Text.vue" import TabSelect from "./TabSelect.vue" import ScrollBox from "./ScrollBox.vue" +import Code from "./Code.vue" +import Diff from "./Diff.vue" +import Textarea from "./Textarea.vue" +import Animation from "./Animation.vue" +import LineNumber from "./LineNumber.vue" import { ref } from "vue" import ExtendExample from "./ExtendExample.vue" -import { useCliRenderer } from ".." +import { useKeyboard } from "@opentui/vue" const exampleOptions = [ - { name: "ASCII", description: "Assci text example", value: "ascii" }, + { name: "ASCII", description: "ASCII text example", value: "ascii" }, { name: "Counter", description: "Counter example", value: "counter" }, { name: "Login Form", description: "A simple login form example", value: "login" }, { name: "Styled Text", description: "Text with various styles applied", value: "styledText" }, { name: "Tab Select", description: "Tabs", value: "tabSelect" }, { name: "Extend", description: "Extend example", value: "extend" }, { name: "ScrollBox", description: "ScrollBox example", value: "scrollBox" }, + { name: "Code", description: "Syntax highlighting demo", value: "code" }, + { name: "Diff", description: "Diff view demo", value: "diff" }, + { name: "Textarea", description: "Interactive editor demo", value: "textarea" }, + { name: "Animation", description: "Timeline animation demo", value: "animation" }, + { name: "Line Number", description: "Line numbers demo", value: "lineNumber" }, ] type ExampleOption = (typeof exampleOptions)[number] @@ -29,8 +39,7 @@ const onSelectExample = (i: number) => { selectedExample.value = selectedOption } -const renderer = useCliRenderer() -renderer.keyInput.on("keypress", (key) => { +useKeyboard((key) => { if (key.name === "escape") { selectedExample.value = null } @@ -48,6 +57,11 @@ const selectStyles = { flexGrow: 1 } + + +