From b42016947bb4aff4ef64a780620dec5146d8eebf Mon Sep 17 00:00:00 2001 From: Sanyam Date: Thu, 13 Aug 2026 13:21:56 +0530 Subject: [PATCH 1/3] chore(site): bump torph to 0.1.0 --- pnpm-lock.yaml | 27 ++++++++++++++++++++++----- site/package.json | 2 +- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a393b0f..8b80fca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -206,8 +206,8 @@ importers: specifier: ^8 version: 8.5.6 torph: - specifier: ^0.0.9 - version: 0.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vue@3.5.24(typescript@5.2.2)) + specifier: ^0.1.0 + version: 0.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vue@3.5.24(typescript@5.2.2)) typescript: specifier: ^5.0.2 version: 5.2.2 @@ -911,36 +911,42 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm-musl@2.5.6': resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.5.6': resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.5.6': resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] '@parcel/watcher-linux-x64-glibc@2.5.6': resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-x64-musl@2.5.6': resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] '@parcel/watcher-win32-arm64@2.5.6': resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} @@ -1009,56 +1015,67 @@ packages: resolution: {integrity: sha512-aL6hRwu0k7MTUESgkg7QHY6CoqPgr6gdQXRJI1/VbFlUMwsSzPGSR7sG5d+MCbYnJmJwThc2ol3nixj1fvI/zQ==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.52.0': resolution: {integrity: sha512-BTs0M5s1EJejgIBJhCeiFo7GZZ2IXWkFGcyZhxX4+8usnIo5Mti57108vjXFIQmmJaRyDwmV59Tw64Ap1dkwMw==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.52.0': resolution: {integrity: sha512-uj672IVOU9m08DBGvoPKPi/J8jlVgjh12C9GmjjBxCTQc3XtVmRkRKyeHSmIKQpvJ7fIm1EJieBUcnGSzDVFyw==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.52.0': resolution: {integrity: sha512-/+IVbeDMDCtB/HP/wiWsSzduD10SEGzIZX2945KSgZRNi4TSkjHqRJtNTVtVb8IRwhJ65ssI56krlLik+zFWkw==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.52.0': resolution: {integrity: sha512-U1vVzvSWtSMWKKrGoROPBXMh3Vwn93TA9V35PldokHGqiUbF6erSzox/5qrSMKp6SzakvyjcPiVF8yB1xKr9Pg==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-gnu@4.52.0': resolution: {integrity: sha512-X/4WfuBAdQRH8cK3DYl8zC00XEE6aM472W+QCycpQJeLWVnHfkv7RyBFVaTqNUMsTgIX8ihMjCvFF9OUgeABzw==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.52.0': resolution: {integrity: sha512-xIRYc58HfWDBZoLmWfWXg2Sq8VCa2iJ32B7mqfWnkx5mekekl0tMe7FHpY8I72RXEcUkaWawRvl3qA55og+cwQ==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.52.0': resolution: {integrity: sha512-mbsoUey05WJIOz8U1WzNdf+6UMYGwE3fZZnQqsM22FZ3wh1N887HT6jAOjXs6CNEK3Ntu2OBsyQDXfIjouI4dw==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.52.0': resolution: {integrity: sha512-qP6aP970bucEi5KKKR4AuPFd8aTx9EF6BvutvYxmZuWLJHmnq4LvBfp0U+yFDMGwJ+AIJEH5sIP+SNypauMWzg==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.52.0': resolution: {integrity: sha512-nmSVN+F2i1yKZ7rJNKO3G7ZzmxJgoQBQZ/6c4MuS553Grmr7WqR7LLDcYG53Z2m9409z3JLt4sCOhLdbKQ3HmA==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.52.0': resolution: {integrity: sha512-2d0qRo33G6TfQVjaMR71P+yJVGODrt5V6+T0BDYH4EMfGgdC/2HWDVjSSFw888GSzAZUwuska3+zxNUCDco6rQ==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openharmony-arm64@4.52.0': resolution: {integrity: sha512-A1JalX4MOaFAAyGgpO7XP5khquv/7xKzLIyLmhNrbiCxWpMlnsTYr8dnsWM7sEeotNmxvSOEL7F65j0HXFcFsw==} @@ -3286,8 +3303,8 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - torph@0.0.9: - resolution: {integrity: sha512-WrFMtJwqXCfIXbLNuTOwHWff0XVm/Ewctb+71bFis3HykPvCXl1CHXapU0r67pQhAI323fsA1L2pGPeqxXeRRA==} + torph@0.1.0: + resolution: {integrity: sha512-2HxoKBIjydwsVilfP44Dawsc6Ou4iL00GgnCvs4raL+Oc8EfY1kKyAxm+wmPYtVRdgdUoSIWUeaaIShNadxQPQ==} peerDependencies: react: '>=18' react-dom: '>=18' @@ -7093,7 +7110,7 @@ snapshots: dependencies: is-number: 7.0.0 - torph@0.0.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vue@3.5.24(typescript@5.2.2)): + torph@0.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(vue@3.5.24(typescript@5.2.2)): optionalDependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) diff --git a/site/package.json b/site/package.json index 1767eb1..b8215ee 100644 --- a/site/package.json +++ b/site/package.json @@ -26,7 +26,7 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", "postcss": "^8", - "torph": "^0.0.9", + "torph": "^0.1.0", "typescript": "^5.0.2", "vite": "^6.4.1" } From c0ad6dd2a34212afd25a9abb4254a980dc5b1c9a Mon Sep 17 00:00:00 2001 From: Sanyam Date: Thu, 13 Aug 2026 13:21:57 +0530 Subject: [PATCH 2/3] feat(site): morph multi-line code blocks torph 0.1.0 renders newlines as morphable segments, so the framework examples and the builder output can animate instead of swapping. --- site/src/surfaces/builder/index.tsx | 5 ++++- site/src/surfaces/usage/index.tsx | 10 +++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/site/src/surfaces/builder/index.tsx b/site/src/surfaces/builder/index.tsx index e7a5e78..0a051cd 100644 --- a/site/src/surfaces/builder/index.tsx +++ b/site/src/surfaces/builder/index.tsx @@ -2,6 +2,7 @@ import { useReducer, useRef, useCallback, useState, useEffect } from "react"; import { motion, AnimatePresence } from "motion/react"; import { defaultPatterns } from "web-haptics"; import type { HapticPreset, Vibration } from "web-haptics"; +import { TextMorph } from "torph/react"; import styles from "./styles.module.scss"; import { useHaptics } from "../../hooks/useHaptics"; @@ -701,7 +702,9 @@ export const HapticBuilder = () => { {/* Code output */} - + + {code} + ); }; diff --git a/site/src/surfaces/usage/index.tsx b/site/src/surfaces/usage/index.tsx index bc40168..cfe5aac 100644 --- a/site/src/surfaces/usage/index.tsx +++ b/site/src/surfaces/usage/index.tsx @@ -2,6 +2,8 @@ import styles from "./styles.module.scss"; import { useState } from "react"; +import { TextMorph } from "torph/react"; + import * as Logos from "./logos"; import { CodeBlock } from "../../components/codeblock"; @@ -69,6 +71,8 @@ export const Usage = () => { const { trigger } = useWebHaptics({ debug }); const [frameworkIndex, setFrameworkIndex] = useState(0); + const example = frameworks[frameworkIndex % frameworks.length].example; + return (
@@ -88,9 +92,9 @@ export const Usage = () => { ))}
- + + {example} +
); }; From 010a2eb1769de36041883a01522477cd41c6b6fa Mon Sep 17 00:00:00 2001 From: Sanyam Date: Thu, 13 Aug 2026 20:35:46 +0530 Subject: [PATCH 3/3] refactor(site): move TextMorph into CodeBlock Every code block morphs now, so the per-surface wrapping and the AutoResize wrapper are both redundant. Sets white-space: pre, because torph's nowrap root drops leading indentation until the first morph. --- site/src/components/codeblock/index.tsx | 10 +++++---- site/src/surfaces/builder/index.tsx | 5 +---- site/src/surfaces/installation/index.tsx | 26 ++++++++++-------------- site/src/surfaces/usage/index.tsx | 10 +++------ 4 files changed, 21 insertions(+), 30 deletions(-) diff --git a/site/src/components/codeblock/index.tsx b/site/src/components/codeblock/index.tsx index 616c05f..2fb5d06 100644 --- a/site/src/components/codeblock/index.tsx +++ b/site/src/components/codeblock/index.tsx @@ -1,16 +1,15 @@ import { useState } from "react"; import styles from "./styles.module.scss"; -import { AutoResize } from "../auto-resizer"; import { TextMorph } from "torph/react"; import { useHaptics } from "../../hooks/useHaptics"; export const CodeBlock = ({ code, - children, + prefix, }: { code: string; - children?: React.ReactNode; + prefix?: React.ReactNode; }) => { const { trigger } = useHaptics(); @@ -34,7 +33,10 @@ export const CodeBlock = ({ {isCopied ? "Copied" : "Copy"}
-        {children ?? code}
+        {prefix}
+        {/* torph's root sets white-space: nowrap, which drops leading
+            indentation until the first morph rewrites it as nbsp segments */}
+        {code}
       
); diff --git a/site/src/surfaces/builder/index.tsx b/site/src/surfaces/builder/index.tsx index 0a051cd..e7a5e78 100644 --- a/site/src/surfaces/builder/index.tsx +++ b/site/src/surfaces/builder/index.tsx @@ -2,7 +2,6 @@ import { useReducer, useRef, useCallback, useState, useEffect } from "react"; import { motion, AnimatePresence } from "motion/react"; import { defaultPatterns } from "web-haptics"; import type { HapticPreset, Vibration } from "web-haptics"; -import { TextMorph } from "torph/react"; import styles from "./styles.module.scss"; import { useHaptics } from "../../hooks/useHaptics"; @@ -702,9 +701,7 @@ export const HapticBuilder = () => { {/* Code output */} - - {code} - + ); }; diff --git a/site/src/surfaces/installation/index.tsx b/site/src/surfaces/installation/index.tsx index 0489ec4..a5add5f 100644 --- a/site/src/surfaces/installation/index.tsx +++ b/site/src/surfaces/installation/index.tsx @@ -2,8 +2,6 @@ import { useState } from "react"; import styles from "./styles.module.scss"; -import { TextMorph } from "torph/react"; - import { CodeBlock } from "../../components/codeblock"; import { useHaptics } from "../../hooks/useHaptics"; @@ -40,19 +38,17 @@ export const InstallCommands = () => {
- - {"$ "} - - - {pkgCmds[Object.keys(pkgCmds)[cmdIndex] as keyof typeof pkgCmds]} - - + prefix={ + + {"$ "} + + } + />
); diff --git a/site/src/surfaces/usage/index.tsx b/site/src/surfaces/usage/index.tsx index cfe5aac..bc40168 100644 --- a/site/src/surfaces/usage/index.tsx +++ b/site/src/surfaces/usage/index.tsx @@ -2,8 +2,6 @@ import styles from "./styles.module.scss"; import { useState } from "react"; -import { TextMorph } from "torph/react"; - import * as Logos from "./logos"; import { CodeBlock } from "../../components/codeblock"; @@ -71,8 +69,6 @@ export const Usage = () => { const { trigger } = useWebHaptics({ debug }); const [frameworkIndex, setFrameworkIndex] = useState(0); - const example = frameworks[frameworkIndex % frameworks.length].example; - return (
@@ -92,9 +88,9 @@ export const Usage = () => { ))}
- - {example} - +
); };