Skip to content

feat(shared-ui): add ShikiCode component for syntax highlighting#482

Merged
luxass merged 4 commits intomainfrom
new-components
Feb 5, 2026
Merged

feat(shared-ui): add ShikiCode component for syntax highlighting#482
luxass merged 4 commits intomainfrom
new-components

Conversation

@luxass
Copy link
Member

@luxass luxass commented Feb 5, 2026

🔗 Linked issue

📚 Description

This PR adds 4 new components. Command, Dialog, ContextMenu and ShikiCode.

Summary by CodeRabbit

  • New Features
    • Added Command Palette UI component for command-based interfaces
    • Added Context Menu UI component with customizable menu actions and states
    • Added Dialog UI component for modal interactions
    • Added syntax-highlighted code display component supporting multiple programming languages and themes

Introduces the `ShikiCode` component, which utilizes the `shiki` library for syntax highlighting. The component allows customization of language and theme, enhancing code presentation in the UI. Additionally, updates the `package.json` to include `shiki` as a dependency and modifies the `tsdown.config.ts` to export the new component.
Introduce `Command` and `Dialog` components to enhance UI functionality. Update aliases in `components.json` for better organization and add new entries in `pnpm-lock.yaml` for `cmdk` package.
@changeset-bot
Copy link

changeset-bot bot commented Feb 5, 2026

⚠️ No Changeset found

Latest commit: cd4ce98

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 5, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This PR updates import alias configurations for the shared UI package and introduces four new UI component modules (ShikiCode, Command, ContextMenu, Dialog) with corresponding package exports and external dependencies (shiki, cmdk).

Changes

Cohort / File(s) Summary
Alias Configuration Updates
apps/web/components.json, packages/shared-ui/components.json, tooling/tsconfig/base.json
Updated UI module import alias mappings from external package paths to local fragment aliases and added TypeScript path alias for component wildcards.
Package Exports & Dependencies
packages/shared-ui/package.json
Added four new component exports (shiki-code, command, context-menu, dialog) and two new dependencies (shiki, cmdk).
ShikiCode Component
packages/shared-ui/src/components/shiki-code.tsx, packages/shared-ui/src/components/index.ts
Implemented syntax-highlighted code component using Shiki with memoization and cached highlighter; exported component and props type.
Command Palette UI
packages/shared-ui/src/ui/command.tsx
Introduced composable command palette UI components wrapping cmdk primitives, including Command, CommandDialog, CommandInput, CommandList, CommandItem, and related utilities.
Context Menu UI
packages/shared-ui/src/ui/context-menu.tsx
Introduced composable context menu UI components with 15 exported variants (root, trigger, content, items, separators, etc.) wrapping primitive components.
Dialog UI
packages/shared-ui/src/ui/dialog.tsx
Introduced composable dialog UI components with 10 exported variants (trigger, overlay, content, header, footer, etc.) with conditional close button support.
Build & Workspace Configuration
packages/shared-ui/tsdown.config.ts, pnpm-workspace.yaml
Updated tsdown entry pattern to include component glob and added workspace-level dependencies for shiki and cmdk.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

Suggested labels

pkg: shared

Poem

🐰 New components hop into place,
Dialog, Command—UI with grace,
Shiki brings syntax in styled sight,
Context menus, polished and bright,
The shared-ui garden takes flight! ✨

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch new-components

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the apps: web Changes related to the Website. label Feb 5, 2026
@luxass luxass marked this pull request as ready for review February 5, 2026 04:31
Copilot AI review requested due to automatic review settings February 5, 2026 04:31
@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

🌏 Preview Deployments

Application Status Preview URL
API ⏭️ Skipped N/A
Website ⏭️ Skipped N/A
Documentation ⏭️ Skipped N/A

Built from commit: cd4ce988f4ea0db2ef076d2a059ceda4dede2a0d


🤖 This comment will be updated automatically when you push new commits to this PR.

@luxass luxass deployed to apps-approval February 5, 2026 04:32 — with GitHub Actions Active
@luxass luxass deployed to apps-deploy February 5, 2026 04:32 — with GitHub Actions Active
@luxass luxass enabled auto-merge February 5, 2026 04:34
@codecov
Copy link

codecov bot commented Feb 5, 2026

Codecov Report

❌ Patch coverage is 0% with 91 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/shared-ui/src/ui/context-menu.tsx 0.00% 35 Missing ⚠️
packages/shared-ui/src/ui/dialog.tsx 0.00% 26 Missing ⚠️
packages/shared-ui/src/ui/command.tsx 0.00% 21 Missing ⚠️
packages/shared-ui/src/components/shiki-code.tsx 0.00% 9 Missing ⚠️

📢 Thoughts on this report? Let us know!

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 adds syntax highlighting capabilities to the shared-ui package by introducing 4 new components: Command, Dialog, ContextMenu, and ShikiCode. The PR adds two new dependencies (shiki 3.22.0 for syntax highlighting and cmdk 1.1.1 for command palette functionality), updates TypeScript configuration to support the new components directory, and modifies build configurations accordingly.

Changes:

  • Adds ShikiCode component for syntax highlighting using the Shiki library
  • Adds Command, Dialog, and ContextMenu UI components built on base-ui/react and cmdk libraries
  • Adds dependencies: shiki (3.22.0) and cmdk (1.1.1)
  • Updates TypeScript path mappings and build configuration to support the new components directory

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
pnpm-workspace.yaml Adds shiki and cmdk to the web catalog
pnpm-lock.yaml Adds dependency entries for shiki 3.22.0 and cmdk 1.1.1
tooling/tsconfig/base.json Adds TypeScript path mapping for components directory
packages/shared-ui/tsdown.config.ts Adds components directory to build entry points
packages/shared-ui/package.json Adds new dependencies and exports for command, dialog, and shiki-code (missing context-menu)
packages/shared-ui/components.json Updates aliases to use shorter # import syntax
apps/web/components.json Corrects ui alias from components to ui
packages/shared-ui/src/ui/dialog.tsx New Dialog component implementation using base-ui
packages/shared-ui/src/ui/context-menu.tsx New ContextMenu component implementation using base-ui
packages/shared-ui/src/ui/command.tsx New Command component implementation using cmdk
packages/shared-ui/src/components/shiki-code.tsx New ShikiCode component for syntax highlighting (has critical issues)
packages/shared-ui/src/components/index.ts Exports for components directory
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

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

Comment on lines +48 to +62
export const ShikiCode = memo<ShikiCodeProps>(({
code,
language = "typescript",
theme = "github-dark",
className,
}) => {
const highlighter = use(getHighlighter());

const html = highlighter.codeToHtml(code, {
lang: language,
theme,
});

// eslint-disable-next-line react-dom/no-dangerously-set-innerhtml
return <div className={className} dangerouslySetInnerHTML={{ __html: html }} />;
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

Using memo() here may be premature optimization. The component performs syntax highlighting on every render regardless of memoization since the html variable is computed inside the component body. The memo wrapper only prevents re-renders when props haven't changed, but the expensive highlighting operation still occurs. Consider computing the html value based on code, language, and theme changes only, or document why memoization is beneficial here.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,63 @@
import type { BundledLanguage, BundledTheme } from "shiki";
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The PR title mentions only "ShikiCode component" but the description states that 4 components are being added (Command, Dialog, ContextMenu, and ShikiCode). The PR title should be updated to reflect the full scope of changes to accurately describe what's being added.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +63
import type { BundledLanguage, BundledTheme } from "shiki";
import { cache, memo, use } from "react";
import { createJavaScriptRegexEngine } from "shiki";
import { createHighlighterCore } from "shiki/core";

export interface ShikiCodeProps {
/**
* The code to highlight
*/
code: string;
/**
* The language to use for syntax highlighting
* @default "typescript"
*/
language?: BundledLanguage;
/**
* The theme to use for syntax highlighting
* @default "github-dark"
*/
theme?: BundledTheme;
/**
* Additional CSS class names
*/
className?: string;
}

const getHighlighter = cache(async () => {
return await createHighlighterCore({
themes: [import("shiki/themes/github-dark.mjs")],
langs: [
import("shiki/langs/javascript.mjs"),
import("shiki/langs/typescript.mjs"),
import("shiki/langs/json.mjs"),
],
engine: createJavaScriptRegexEngine(),
});
});

/**
* A syntax highlighting component powered by Shiki.
* Renders code to HTML with syntax highlighting.
*
* @example
* ```tsx
* <ShikiCode code="const x = 1;" language="typescript" />
* ```
*/
export const ShikiCode = memo<ShikiCodeProps>(({
code,
language = "typescript",
theme = "github-dark",
className,
}) => {
const highlighter = use(getHighlighter());

const html = highlighter.codeToHtml(code, {
lang: language,
theme,
});

// eslint-disable-next-line react-dom/no-dangerously-set-innerhtml
return <div className={className} dangerouslySetInnerHTML={{ __html: html }} />;
});
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The component uses React's cache function and the use hook with an async function, which are server component patterns. However, the component is not explicitly marked with 'use server' directive. If this component is intended to be a server component, add the 'use server' directive at the top of the file. If it's meant to be a client component, this pattern won't work - you'll need to precompute the highlighted HTML on the server or use a different approach for client-side rendering.

Copilot uses AI. Check for mistakes.
"./ui/collapsible": "./dist/ui/collapsible.mjs",
"./ui/combobox": "./dist/ui/combobox.mjs",
"./ui/command": "./dist/ui/command.mjs",
"./ui/context-menu": "./dist/ui/context-menu.mjs",
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The ContextMenu component is implemented but missing from the package.json exports. This component cannot be imported by consumers of the package. Add an export entry for "./ui/context-menu" pointing to "./dist/ui/context-menu.mjs".

Copilot uses AI. Check for mistakes.
@luxass luxass merged commit 1501357 into main Feb 5, 2026
28 of 30 checks passed
@luxass luxass deleted the new-components branch February 5, 2026 04:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

apps: web Changes related to the Website.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant