Skip to content

CodeBlock

KCodeBlock is a code block component with built-in search and filter functionalities.

Searching highlights matching lines within the code while filtering shows only matching line (i.e. like the Unix grep command does).

Searching and filtering can happen by exact matches (the default) and by matching regular expressions. The search-related UI controls can also be interacted with using keyboard shortcuts.

html
<KCodeBlock
  id="code-block-default"
  :code="code"
  language="json"
  searchable
/>

Props

id

An ID used to identify form elements like the search input and its label. This prop is required.

Note: If you use multiple instances of KCodeBlock in a document, you need to provide unique ID values.

code

The code that will be rendered as a text node inside of a <pre><code></code></pre> element. This prop is required.

No additional formatting of the code takes places. It will be used as-is.

language

The syntax language of props.code (e.g. 'json'). This prop is also required.

initialFilterMode

Boolean to control whether the filter mode is initially active. Can be used together with the filter-mode-change event to persist a code block’s filter mode setting. Defaults to false.

initialRegExpMode

Boolean to control whether the regular expression mode is initially active. Can be used together with the reg-exp-mode-change event to persist a code block’s regular expression mode setting. Defaults to false.

html
<KCodeBlock
  id="code-block-initial-reg-exp-mode"
  :code="code"
  language="json"
  query="(true|false)"
  initial-filter-mode
  initial-reg-exp-mode
  searchable
/>

searchable

Boolean to control whether to show or hide the search bar and related action buttons. Defaults to false.

html
<KCodeBlock
  id="code-block-searchable"
  :code="code"
  language="json"
  searchable
/>

singleLine

Whether the code passed into the component should be displayed on a single line. Defaults to false.

NOTE

Please keep the following in mind when using singleLine:

  • Line numbers will not be displayed
  • Code will not be searchable
  • Multi-line code snippets will have \n stripped out to allow displaying the code on a single line. Code copied by clicking the copy button will contain any \n in the original code.
html
<KCodeBlock
  id="code-block-single-line"
  :code="cert"
  single-line
  language="plaintext"
/>

processing

Allows controlling the processing state from outside the component. This allows a parent component to show the processing icon when it’s, for example, currently syntax highlighting the code.

html
<KCodeBlock
  id="code-block-processing"
  :code="code"
  language="json"
  processing
/>

maxHeight

The max-height of the code block. Default value is none.

html
<KCodeBlock
  id="code-block-max-height"
  :code="code"
  language="json"
  max-height="200"
/>

query

Used as the initial value of the search input. Can be used to initialize a code block with a query which was read from client storage.

html
<KCodeBlock
  id="code-block-query"
  :code="code"
  language="json"
  searchable
  query="no"
  max-height="200"
/>

showCopyButton

Controls whether to show a copy button which copies the original code (the value of props.code) to the clipboard. Defaults to true.

html
<KCodeBlock
  id="code-block-show-copy-button"
  :code="code"
  language="json"
  :show-copy-button="false"
/>

Controls whether to add links to the current line number. Defaults to false.

You might need to turn this off for sites that already constantly use the fragment identifier in the URL like vue router’s hash-based navigation mode where all URL paths follow a first /#/ segment.

html
<KCodeBlock
  id="code-block-show-line-number-links"
  :code="code"
  language="json"
  :show-line-number-links="true"
/>

theme

Sets the display theme of the component. Accepted values are:

  • light (default)
  • dark
html
<KCodeBlock
  id="code-block-dark-theme"
  :code="code"
  language="json"
  theme="dark"
  searchable
/>

Slots

secondary-actions

Allows adding elements after the location of the copy button. See example in KCodeBlockIconButton component docs section.

KCodeBlockIconButton

KCodeBlockIconButton is a helper component for adding KCodeBlock-style icon buttons. It works just like a regular button with a few props expanding it's functionality.

Props

theme

Pass the value matching the theme prop value passed to KCodeBlock component so that the button style matches the theme. Note: it's also a good idea to combine this prop with appropriate accessibility attributes such as aria-pressed.

active

Use this prop for buttons that can have two states: active and inactive (e.g. filter mode button). This will apply appropriate state styling to the button. Defaults to true.

copyTooltip

If the button action is copying some content to the clipboard, you can pass test through this prop that will be displayed as tooltip on the button. Once the button is clicked, the tooltip text will change to "Copied!" for a few seconds before changing back to the original value you passed.

Slots

default

Slot for button content.

html
<KCodeBlock
  id="code-block-slots-secondary-actions"
  :code="code"
  language="json"
>
  <template #secondary-actions>
    <KCodeBlockIconButton copy-tooltip="Copy as k8s">
      <CopyIcon />
      as k8s
    </KCodeBlockIconButton>
  </template>
</KCodeBlock>

Events

code-block-render

Fired when the code block is rendered or re-rendered. This happens when:

  • the component’s mounted life cycle hook is fired
  • the filter mode is turned off
  • props.code changes

Event payload is object instance of type CodeBlockEventData.

ts
interface CodeBlockEventData {
  preElement: HTMLElement
  codeElement: HTMLElement
  code: string
  language: string
  query: string
  matchingLineNumbers: number[]
}

This event can be used as the trigger for applying syntax highlighting (e.g. via Prism’s highlightElement function, see Syntax highlighting for an integration example).

javascript
function highlight({ preElement, codeElement, language, code }) {
  if (!preElement.classList.contains(`language-${language}`)) {
    preElement.classList.add(`language-${language}`)
  }

  codeElement.innerHTML = code

  Prism.highlightElement(codeElement)
}

filter-mode-change

Fired when the toggles the filter mode.

matching-lines-change

Fired when the lines matching a query change. Event payload is object instance of type CodeBlockEventData.

query-change

Fired when the component’s internal query state is updated. This happens when the user finished typing (with a delay of a few hundred milliseconds to avoid repeatedly triggering computations while the user is still typing).

reg-exp-mode-change

Fired when the toggles the regular expression mode.

Default shortcuts

This component has a few shortcuts for interacting with its search and filter features. All of them are scoped to the code block. When invoking them while focus is placed outside of a code block, their associated actions won’t trigger.

ShortcutDescription
Alt+F or Alt+GToggles filter mode
Alt+RToggles RegExp mode
Alt+CCopies the code
F3 or EnterJumps to next match
Shift+F3 or Shift+EnterJumps to previous match

Syntax highlighting

The KCodeBlock component does not have syntax highlighting built in; however, your project can provide its own implementation.

PrismJS

Below is an integration example for the popular syntax highlighting library PrismJS.

It makes use of the code-block-render event to apply syntax highlighting.

html
<template>
  <KCodeBlock
    id="code-block"
    :code="code"
    language="json"
    :processing="processing"
    searchable
    @code-block-render="highlight"
    @matching-lines-change="highlightLines"
  />
</template>

<script setup>
import { ref } from 'vue'
import { KCodeBlock } from '@kong/kongponents/KCodeBlock.vue'
import Prism from 'prismjs'
import 'prismjs/components/prism-json.min.js'

import 'prismjs/themes/prism.min.css'

Prism.manual = true

const code = `{
  "compilerOptions": {
    "target": "es2020",
    "module": "esnext",
    "moduleResolution": "node",
    "allowUnreachableCode": false,
    "exactOptionalPropertyTypes": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noUncheckedIndexedAccess": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "strict": true,
    "jsx": "preserve"
  },
  "include": [
    "./src",
    "./types"
  ]
}`

const processing = ref(false)

/**
 * Applies PrismJS syntax highlighting.
 *
 * **Note**: Use higher-level functions like `Prism.highlightElement` for highlighting.
 * Lower-level functions like `Prism.highlight` don’t run any of the hooks
 * that are used to make plugins work.
 */
function highlight({ preElement, codeElement, language, code }) {
  processing.value = true

  if (!Prism.languages[language]) {
    console.warn(`Prism: the language “${language}” isn’t enabled.`)
  }

  if (!preElement.classList.contains(`language-${language}`)) {
    // Adds the language-* class which tells Prism which language to highlight for.
    preElement.classList.add(`language-${language}`)
  }

  // Ensures Prism operates on the raw code and not on an already highlighted DOM fragment.
  codeElement.innerHTML = code

  Prism.highlightElement(codeElement)

  processing.value = false
}
</script>

Released under the Apache-2.0 License.