Skip to content

@gpuix/react@0.4.0

Choose a tag to compare

@remorses remorses released this 23 Aug 15:10
· 140 commits to main since this release

Also ships @gpuix/native@0.4.0. CI publishes both packages.

  1. Native motion.div animations — animate from an initial style to a target style. React sends the targets once. Rust interpolates the presentation style and requests GPUI frames. The React tree is not reconciled on each frame.

    import { motion } from '@gpuix/react'
    
    <motion.div
      initial={{ width: 0, opacity: 0 }}
      animate={{ width: 260, opacity: 1 }}
      transition={{ duration: 0.2, ease: 'easeOut' }}
    >
      Sidebar content
    </motion.div>

    Numeric targets: width, height, top, right, bottom, left, opacity, borderRadius. Timing uses seconds. ease is "linear", "ease", "easeIn", "easeOut", "easeInOut", or a cubic-bezier [x1, y1, x2, y2].

    Set initial={false} to mount at the first animate target. A running animation can reverse or change target without a jump.

  2. Playwright-like automation API — mark elements with testId, then drive them from tests or from another process.

    import { connectTest } from '@gpuix/react/automation'
    
    const app = await connectTest(renderer)
    await app.getByTestId('inc').click()
    await app.getByText('Count: 1').waitFor()
    await app.getByTestId('composer').fill('hello gpuix')
    await app.getByTestId('composer').press('enter')
    await app.captureFrames('review/sidebar', [0, 150, 300])

    Locators: getByTestId, getByText, getByType. app.clock.pause(), set(ms), and fastForward(ms) freeze native motion time.

    A live app listens on stdin when stdin is a pipe. launch({ command, args }) pipes stdin and speaks SSE data: lines:

    import { launch } from '@gpuix/react/automation'
    
    const app = await launch({ command: 'bun', args: ['examples/chat.tsx'] })
    await app.getByTestId('composer').fill('hello')
    await app.screenshot({ path: 'live.png' })
    await app.close()