Skip to content

Commit

Permalink
chore: update readme (#16)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
mattcroat and antfu authored May 10, 2024
1 parent 196ea47 commit 6b6dd9c
Showing 1 changed file with 110 additions and 10 deletions.
120 changes: 110 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,42 @@

Smoothly animated code blocks with Shiki. [Online Demo](https://shiki-magic-move.netlify.app/).

## Usage

This is a rather low-level library, you usually want to use it with a high-level integrations like [Slidev](https://sli.dev/guide/syntax#shiki-magic-move).
Shiki Magic Move is a low-level library for animating code blocks, and uses [Shiki](https://shiki.style/) as the syntax highlighter. You usually want to use it with a high-level integration like [Slidev](https://sli.dev/guide/syntax#shiki-magic-move).

The package provides framework-agnostic [core](./src/core.ts) and [renderer](./src/renderer.ts) and framework wrappers for [Vue](./src/vue) and [React](./src/react).
At the core of the `shiki-magic-move` package is a framework-agnostic [core](./src/core.ts), and [renderer](./src/renderer.ts) — there are also framework wrappers for [Vue](./src/vue), [React](./src/react), and [Svelte](./src/svelte).

Each of the framework wrappers provides the following components:

- `ShikiMagicMove` - the main component to wrap the code block
- `ShikiMagicMovePrecompiled` - animations for compiled tokens, without the dependency on Shiki
- `ShikiMagicMoveRenderer` - the low-level renderer component

### `ShikiMagicMove`
The `ShikiMagicMove` component requires you to provide a Shiki highlighter instance, and the styles are also required, and provided by `shiki-magic-move`. Whenever the `code` changes, the component will animate the changes.

## Installation

You're going to need Shiki Magic Move for animating the code blocks, and Shiki for syntax highlighting.

```bash
npm i shiki-magic-move shiki
```

## Usage

### Vue

`ShikiMagicMove` requires you to provide a Shiki highlighter instance. For example, in Vue:
Import `shiki-magic-move/vue`, and pass the highlighter instance to the `ShikiMagicMove` component.

```vue
<script setup>
import { ShikiMagicMove } from 'shiki-magic-move/vue'
import { getHighlighter } from 'shiki'
import { ref } from 'vue'
import 'shiki-magic-move/dist/style.css'
const highlighter = await getHighlighter({
theme: 'nord',
themes: ['nord'],
langs: ['javascript', 'typescript'],
})
Expand All @@ -43,14 +55,102 @@ function animate() {
</script>
<template>
<ShikiMagicMove :highlighter="highlighter" lang="ts" :code="code" />
<ShikiMagicMove
lang="ts"
theme="nord"
:highlighter="highlighter"
:code="code"
:options="{ duration: 800, stagger: 0.3, lineNumbers: true }"
/>
<button @click="animate">
Animate
</button>
</template>
```

Whenever the `code` changes, the component will animate the changes.
### React

Import `shiki-magic-move/react`, and pass the highlighter instance to the `ShikiMagicMove` component.

```tsx
import { useEffect, useState } from 'react'
import { ShikiMagicMove } from 'shiki-magic-move/react'
import { type HighlighterCore, getHighlighter } from 'shiki'

import 'shiki-magic-move/dist/style.css'

function App() {
const [code, setCode] = useState(`const hello = 'world'`)
const [highlighter, setHighlighter] = useState<HighlighterCore>()

useEffect(() => {
async function initializeHighlighter() {
const highlighter = await getHighlighter({
themes: ['nord'],
langs: ['javascript', 'typescript'],
})
setHighlighter(highlighter)
}
initializeHighlighter()
}, [])

function animate() {
setCode(`let hi = 'hello'`)
}

return (
<div>
{highlighter && (
<>
<ShikiMagicMove
lang="ts"
theme="nord"
highlighter={highlighter}
code={code}
options={{ duration: 800, stagger: 0.3, lineNumbers: true }}
/>
<button onClick={animate}>Animate</button>
</>
)}
</div>
)
}
```

### Svelte

Import `shiki-magic-move/svelte`, and pass the highlighter instance to the `ShikiMagicMove` component.

```svelte
<script lang='ts'>
import { ShikiMagicMove } from 'shiki-magic-move/svelte'
import { getHighlighter } from 'shiki'
import 'shiki-magic-move/dist/style.css'
const highlighter = getHighlighter({
themes: ['nord'],
langs: ['javascript', 'typescript'],
})
let code = $state(`const hello = 'world'`)
function animate() {
code = `let hi = 'hello'`
}
</script>
{#await highlighter then highlighter}
<ShikiMagicMove
lang='ts'
theme='nord'
{highlighter}
{code}
options={{ duration: 800, stagger: 0.3, lineNumbers: true }}
/>
<button onclick={animate}>Animate</button>
{/await}
```

### `ShikiMagicMovePrecompiled`

Expand Down Expand Up @@ -110,7 +210,7 @@ const compiledSteps = codeSteps.map(code => machine.commit(code).current)

## How it works

Check [this blog post](https://antfu.me/posts/shiki-magic-move).
You can read [The Magic In Shiki Magic Move](https://antfu.me/posts/shiki-magic-move) to understand how Shiki Magic Move works.

## Sponsors

Expand Down

0 comments on commit 6b6dd9c

Please sign in to comment.