import { createApp } from 'vue'
import App from './App.vue'
import '@hina-ui/vue/styles/tokens.css'
createApp(App).mount('#app')<script setup lang="ts">
import { CodeBlock } from '@hina-ui/vue'
const source = `import { createApp } from 'vue'
import App from './App.vue'
import '@hina-ui/vue/styles/tokens.css'
createApp(App).mount('#app')`
</script>
<template>
<CodeBlock :code="source" lang="ts" class="w-full max-w-xl" />
</template>
Usage
import { CodeBlock } from '@hina-ui/vue'
code is required and is rendered verbatim. lang names the language, which drives highlighting and the badge in the top corner.
pnpm add @hina-ui/vue<script setup lang="ts">
import { CodeBlock } from '@hina-ui/vue'
</script>
<template>
<CodeBlock code="pnpm add @hina-ui/vue" lang="bash" class="w-full max-w-xl" />
</template>
Examples
Badge text
The badge shows lang by default. Set label to show a file name or another note instead; highlighting still follows lang.
export default defineNuxtConfig({
css: ['@hina-ui/vue/styles/tokens.css'],
})<script setup lang="ts">
import { CodeBlock } from '@hina-ui/vue'
const source = `export default defineNuxtConfig({
css: ['@hina-ui/vue/styles/tokens.css'],
})`
</script>
<template>
<CodeBlock :code="source" lang="ts" label="nuxt.config.ts" class="w-full max-w-xl" />
</template>
Without highlighting
With no lang, nothing is highlighted and no badge is shown; the code appears as written. Command output and plain text suit this.
✔ dependencies installed
✔ style entry ready
run pnpm dev to start the dev server<script setup lang="ts">
import { CodeBlock } from '@hina-ui/vue'
const output = `✔ dependencies installed
✔ style entry ready
run pnpm dev to start the dev server`
</script>
<template>
<CodeBlock :code="output" class="w-full max-w-xl" />
</template>
Copy button
A copy button sits in the top corner by default. Set copyable to false to remove it.
git switch -c feature/hina-ui<script setup lang="ts">
import { CodeBlock } from '@hina-ui/vue'
</script>
<template>
<CodeBlock
code="git switch -c feature/hina-ui"
lang="bash"
:copyable="false"
class="w-full max-w-xl"
/>
</template>
Long lines
Code does not wrap. Anything wider than the block scrolls horizontally inside it, so the page itself is never stretched. The scrolling area can take focus, after which arrow keys scroll it.
const theme = { accent: 'var(--hn-accent)', radius: 'var(--hn-radius-lg)', shadow: 'var(--hn-shadow-sm)', font: 'var(--hn-font-sans)' }<script setup lang="ts">
import { CodeBlock } from '@hina-ui/vue'
const source = `const theme = { accent: 'var(--hn-accent)', radius: 'var(--hn-radius-lg)', shadow: 'var(--hn-shadow-sm)', font: 'var(--hn-font-sans)' }`
</script>
<template>
<CodeBlock :code="source" lang="ts" class="w-full max-w-md" />
</template>
Height
Set height through class or style to scroll overflowing code vertically. Long lines still scroll horizontally, while the badge and copy button stay in the top corner.
const value1 = { name: 'Hina UI', enabled: true }
const value2 = { name: 'Hina UI', enabled: true }
const value3 = { name: 'Hina UI', enabled: true }
const value4 = { name: 'Hina UI', enabled: true }
const value5 = { name: 'Hina UI', enabled: true }
const value6 = { name: 'Hina UI', enabled: true }
const value7 = { name: 'Hina UI', enabled: true }
const value8 = { name: 'Hina UI', enabled: true }
const value9 = { name: 'Hina UI', enabled: true }
const value10 = { name: 'Hina UI', enabled: true }
const value11 = { name: 'Hina UI', enabled: true }
const value12 = { name: 'Hina UI', enabled: true }
const value13 = { name: 'Hina UI', enabled: true }
const value14 = { name: 'Hina UI', enabled: true }
const value15 = { name: 'Hina UI', enabled: true }
const value16 = { name: 'Hina UI', enabled: true }<script setup lang="ts">
import { CodeBlock } from '@hina-ui/vue'
const source = Array.from(
{ length: 16 },
(_, index) => 'const value' + (index + 1) + " = { name: 'Hina UI', enabled: true }",
).join('\n')
</script>
<template>
<CodeBlock :code="source" lang="ts" class="h-48 w-full max-w-lg" />
</template>
Set max-height to limit the height. Short content keeps its natural height; vertical scrolling starts when the content exceeds the limit.
const value1 = { name: 'Hina UI', enabled: true }
const value2 = { name: 'Hina UI', enabled: true }
const value3 = { name: 'Hina UI', enabled: true }
const value4 = { name: 'Hina UI', enabled: true }
const value5 = { name: 'Hina UI', enabled: true }
const value6 = { name: 'Hina UI', enabled: true }
const value7 = { name: 'Hina UI', enabled: true }
const value8 = { name: 'Hina UI', enabled: true }
const value9 = { name: 'Hina UI', enabled: true }
const value10 = { name: 'Hina UI', enabled: true }
const value11 = { name: 'Hina UI', enabled: true }
const value12 = { name: 'Hina UI', enabled: true }
const value13 = { name: 'Hina UI', enabled: true }
const value14 = { name: 'Hina UI', enabled: true }
const value15 = { name: 'Hina UI', enabled: true }
const value16 = { name: 'Hina UI', enabled: true }<script setup lang="ts">
import { CodeBlock } from '@hina-ui/vue'
const source = Array.from(
{ length: 16 },
(_, index) => 'const value' + (index + 1) + " = { name: 'Hina UI', enabled: true }",
).join('\n')
</script>
<template>
<CodeBlock :code="source" lang="ts" class="max-h-48 w-full max-w-lg" />
</template>
Pre-highlighted code
The html property accepts markup that has already been highlighted. Once given, the component skips highlighting and renders that markup directly, while code is still used for copying.
Highlighting on the server or at build time keeps the browser from downloading a highlighter. Every code block on this site works that way.
const accent = '#39c5bb'<script setup lang="ts">
import { CodeBlock } from '@hina-ui/vue'
const code = `const accent = '#39c5bb'`
const html = `<span style="color:#8250df">const</span><span> accent = </span><span style="color:#0a3069">'#39c5bb'</span>`
</script>
<template>
<CodeBlock :code="code" :html="html" lang="ts" class="w-full max-w-xl" />
</template>
Accessibility
- The scrolling area can take focus and is then scrolled with arrow keys; the focus ring appears around the block.
- The accessible name of that area comes from the badge, falling back to a generic name when no badge is set.
- The copy button is named “Copy code” and becomes “Copied” on success.
API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
code | string | — | Required. The code text, also used for copying |
lang | string | — | Language, driving highlighting and the badge |
label | string | — | Badge text, overriding lang |
html | string | — | Pre-highlighted markup; skips highlighting |
copyable | boolean | true | Whether to show the copy button |
class | string | — | Classes appended to the root |