Skip to content

feat(kcodeblock): introduce new function prop codeRenderer for syntax highlighting#3139

Closed
kingyue737 wants to merge 3 commits intomainfrom
feat/kcodeblock-code-renderer-prop
Closed

feat(kcodeblock): introduce new function prop codeRenderer for syntax highlighting#3139
kingyue737 wants to merge 3 commits intomainfrom
feat/kcodeblock-code-renderer-prop

Conversation

@kingyue737
Copy link
Member

@kingyue737 kingyue737 commented Mar 17, 2026

Summary

This PR adds a codeRenderer function prop to KCodeBlock for flicker-free syntax highlighting.

Previously, applying syntax highlighting required listening to @code-block-render and mutating codeElement.innerHTML which causes a flash of unstyled code:

Screen.Recording.2026-01-13.at.14.12.37.mov

With codeRenderer, the component awaits the returned HTML internally before rendering, so unstyled code is never visible. On subsequent updates, the previous highlighted content stays visible until the new result arrives. This also helps eliminate flaky tests caused by syntax highlighters in consumer apps. Previously, tests could observe the un-highlighted code before the highlighter replaced it.

@netlify
Copy link

netlify bot commented Mar 17, 2026

Deploy Preview for kongponents-sandbox ready!

Name Link
🔨 Latest commit 98b68c6
🔍 Latest deploy log https://app.netlify.com/projects/kongponents-sandbox/deploys/69ba761889e498000838e89e
😎 Deploy Preview https://deploy-preview-3139--kongponents-sandbox.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Mar 17, 2026

Deploy Preview for kongponents ready!

Name Link
🔨 Latest commit 98b68c6
🔍 Latest deploy log https://app.netlify.com/projects/kongponents/deploys/69ba7619ae0a2100084ac322
😎 Deploy Preview https://deploy-preview-3139--kongponents.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new codeRenderer prop for KCodeBlock to enable consumer-provided (async or sync) HTML rendering for syntax highlighting, and updates docs/sandbox/tests to demonstrate and validate the new API.

Changes:

  • Added CodeBlockRenderData type and a new codeRenderer prop to CodeBlockProps.
  • Updated KCodeBlock to await codeRenderer output and render it via v-html, including a pending/hidden initial state.
  • Added Cypress coverage plus updated sandbox and docs to use codeRenderer instead of the code-block-render event for highlighting examples.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/types/code-block.ts Introduces CodeBlockRenderData and the codeRenderer prop typing.
src/components/KCodeBlock/KCodeBlock.vue Implements async rendering pipeline (applyCodeRenderer, pending state, updated watchers).
src/components/KCodeBlock/KCodeBlock.cy.ts Adds Cypress tests to validate codeRenderer behavior (mount, updates, pending, event timing).
sandbox/pages/SandboxCodeBlock.vue Updates sandbox highlighting integration to return HTML via codeRenderer.
docs/components/codeblock.md Documents codeRenderer and updates syntax-highlighting examples and guidance.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new codeRenderer function prop to KCodeBlock to enable flicker-free (async) syntax highlighting by letting the component await highlighted HTML before showing code.

Changes:

  • Introduces CodeBlockRenderData and adds codeRenderer to CodeBlockProps.
  • Updates KCodeBlock to optionally render codeRenderer output with a pending/hidden state while rendering resolves.
  • Adds Cypress coverage for codeRenderer, updates sandbox usage, and documents the new prop + updated syntax-highlighting guidance.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/types/code-block.ts Adds CodeBlockRenderData and the new codeRenderer prop type.
src/components/KCodeBlock/KCodeBlock.vue Implements async rendering flow, pending state, and adjusts watchers/mount behavior.
src/components/KCodeBlock/KCodeBlock.cy.ts Adds component tests covering codeRenderer behavior and event timing.
sandbox/pages/SandboxCodeBlock.vue Migrates sandbox highlighting example from event-based mutation to codeRenderer.
docs/components/codeblock.md Documents codeRenderer and updates syntax-highlighting guidance/examples.
Comments suppressed due to low confidence (1)

src/components/KCodeBlock/KCodeBlock.vue:550

  • codeRenderer is awaited before updateMatchingLineNumbers()/setDefaultMatchingLineNumbers() on mount. With an initial query prop (or any expensive renderer), this delays match calculation/UI state and also means codeRenderer receives matchingLineNumbers that may still reflect the previous/default state. Consider computing matching lines first (or in parallel), and only delaying the code-block-render emit / visibility until the renderer resolves.
onMounted(async function() {
  shortcutManager.registerListener()

  if (codeRenderer) {
    await applyCodeRenderer()
  }

  emitCodeBlockRenderEvent()

  if (!queryProp && highlightedLineNumbers.length) {
    setDefaultMatchingLineNumbers()
  } else {
    updateMatchingLineNumbers()
  }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +936 to +939

&.render-pending {
visibility: hidden;
}
@kingyue737 kingyue737 marked this pull request as ready for review March 17, 2026 10:30
@kongponents-bot
Copy link
Collaborator

🔴 PR audit failed. 🔴

🔥 Renovate Security PRs detected.

There are 2 open renovate security PRs older than 3 days.

This PR cannot be merged until all renovate security PRs created more than 3 days ago are resolved.

🔥 PNPM Audit issues detected.

┌─────────────────────┬────────────────────────────────────────────────────────┐
│ high                │ flatted vulnerable to unbounded recursion DoS in       │
│                     │ parse() revive phase                                   │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Package             │ flatted                                                │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Vulnerable versions │ <3.4.0                                                 │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Patched versions    │ >=3.4.0                                                │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Paths               │ .>eslint>file-entry-cache>flat-cache>flatted           │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ More info           │ https://github.com/advisories/GHSA-25h7-pfq9-p65f      │
└─────────────────────┴────────────────────────────────────────────────────────┘
┌─────────────────────┬────────────────────────────────────────────────────────┐
│ high                │ Undici: Malicious WebSocket 64-bit length overflows    │
│                     │ parser and crashes the client                          │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Package             │ undici                                                 │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Vulnerable versions │ >=7.0.0 <7.24.0                                        │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Patched versions    │ >=7.24.0                                               │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Paths               │ .>semantic-release>@semantic-release/github>undici     │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ More info           │ https://github.com/advisories/GHSA-f269-vfmq-vjvj      │
└─────────────────────┴────────────────────────────────────────────────────────┘
┌─────────────────────┬────────────────────────────────────────────────────────┐
│ high                │ Undici: Malicious WebSocket 64-bit length overflows    │
│                     │ parser and crashes the client                          │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Package             │ undici                                                 │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Vulnerable versions │ >=6.0.0 <6.24.0                                        │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Patched versions    │ >=6.24.0                                               │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Paths               │ .>semantic-release>@semantic-release/npm>@actions/     │
│                     │ core>@actions/http-client>undici                       │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ More info           │ https://github.com/advisories/GHSA-f269-vfmq-vjvj      │
└─────────────────────┴────────────────────────────────────────────────────────┘
┌─────────────────────┬────────────────────────────────────────────────────────┐
│ high                │ Undici has Unbounded Memory Consumption in WebSocket   │
│                     │ permessage-deflate Decompression                       │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Package             │ undici                                                 │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Vulnerable versions │ >=7.0.0 <7.24.0                                        │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Patched versions    │ >=7.24.0                                               │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Paths               │ .>semantic-release>@semantic-release/github>undici     │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ More info           │ https://github.com/advisories/GHSA-vrm6-8vpv-qv8q      │
└─────────────────────┴────────────────────────────────────────────────────────┘
┌─────────────────────┬────────────────────────────────────────────────────────┐
│ high                │ Undici has Unbounded Memory Consumption in WebSocket   │
│                     │ permessage-deflate Decompression                       │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Package             │ undici                                                 │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Vulnerable versions │ <6.24.0                                                │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Patched versions    │ >=6.24.0                                               │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Paths               │ .>semantic-release>@semantic-release/npm>@actions/     │
│                     │ core>@actions/http-client>undici                       │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ More info           │ https://github.com/advisories/GHSA-vrm6-8vpv-qv8q      │
└─────────────────────┴────────────────────────────────────────────────────────┘
┌─────────────────────┬────────────────────────────────────────────────────────┐
│ high                │ Undici has Unhandled Exception in WebSocket Client Due │
│                     │ to Invalid server_max_window_bits Validation           │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Package             │ undici                                                 │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Vulnerable versions │ >=7.0.0 <7.24.0                                        │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Patched versions    │ >=7.24.0                                               │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Paths               │ .>semantic-release>@semantic-release/github>undici     │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ More info           │ https://github.com/advisories/GHSA-v9p9-hfj2-hcw8      │
└─────────────────────┴────────────────────────────────────────────────────────┘
┌─────────────────────┬────────────────────────────────────────────────────────┐
│ high                │ Undici has Unhandled Exception in WebSocket Client Due │
│                     │ to Invalid server_max_window_bits Validation           │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Package             │ undici                                                 │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Vulnerable versions │ <6.24.0                                                │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Patched versions    │ >=6.24.0                                               │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ Paths               │ .>semantic-release>@semantic-release/npm>@actions/     │
│                     │ core>@actions/http-client>undici                       │
├─────────────────────┼────────────────────────────────────────────────────────┤
│ More info           │ https://github.com/advisories/GHSA-v9p9-hfj2-hcw8      │
└─────────────────────┴────────────────────────────────────────────────────────┘
7 vulnerabilities found
Severity: 7 high

PR with those issues cannot be merged.

How to resolve:

  • Check open renovate PRs for updates to the dependencies mentioned in the audit report
  • try to update dependencies listed in the audit report to the latest versions
  • use pnpm audit --fix to automatically fix issues

@kongponents-bot
Copy link
Collaborator

Preview package from this PR in consuming application

In consuming application project install preview version of kongponents generated by this PR:

@kong/kongponents@pr-3139

@kingyue737 kingyue737 closed this Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants