🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Sign inDemoInstall
Socket

react-shiki

Package Overview
Dependencies
Maintainers
0
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-shiki - npm Package Compare versions

Comparing version

to
0.3.0

dist/index.d.ts

5

dist/index.js

@@ -1,3 +0,4 @@

function c(e,{insertAt:t}={}){if(!e||typeof document>"u")return;let i=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css",t==="top"&&i.firstChild?i.insertBefore(r,i.firstChild):i.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}c(`.relative{position:relative}.defaultStyles pre{overflow:auto;border-radius:.5rem;padding:1.25rem 1.5rem}.languageLabel{position:absolute;right:.75rem;top:.5rem;font-family:monospace;font-size:.75rem;letter-spacing:-.05em;color:#6b7280d9}
`);import y from"react";import{clsx as x}from"clsx";import{useEffect as b,useRef as w,useState as k}from"react";import E from"html-react-parser";import{createHighlighter as L,ShikiError as f}from"shiki";import{visit as T}from"unist-util-visit";function S(){return function(e){T(e,"element",function(t,i,r){r&&r.tagName==="pre"?t.properties.inline=!1:t.properties.inline=!0})}}var H=e=>e.position?.start.line===e.position?.end.line,u={pre(e){return"properties"in e&&(e.properties.tabindex="-1"),e}};var d=null,P=async e=>{d||(d=L({themes:[],langs:[]}));let t=await d;return await R(t,e),t},R=async(e,t)=>{try{await e.loadTheme(t)}catch(i){throw i instanceof f&&console.warn("Error loading theme:",i.message),i}},C=async(e,t)=>{let i=t??"plaintext";try{return await e.loadLanguage(i),i}catch(r){return r instanceof f&&r.message.includes("not included in this bundle")&&console.warn(`Language '${i}' not supported, falling back to plaintext`),"plaintext"}},I=(e,t,i)=>{let r=Date.now();clearTimeout(t.current.timeoutId);let n=Math.max(0,t.current.nextAllowedTime-r);t.current.timeoutId=setTimeout(()=>{e().catch(console.error),t.current.nextAllowedTime=r+i},n)},p=(e,t,i,r={})=>{let[n,h]=k(null),o=w({nextAllowedTime:0,timeoutId:void 0});return b(()=>{let a=!0,l=async()=>{let s=await P(i),m=await C(s,t),g=s.codeToHtml(e,{lang:m,theme:i,transformers:[u]});a&&h(E(g))};return r.delay?I(l,o,r.delay):l().catch(console.error),()=>{a=!1,clearTimeout(o.current.timeoutId)}},[e,t]),n};var v=({language:e,theme:t,delay:i,addDefaultStyles:r=!0,style:n,langStyle:h,className:o,langClassName:a,showLanguage:l=!0,children:s,as:m="pre"})=>{let g=p(s,e,t,{delay:i});return y.createElement(m,{className:x("relative","not-prose",r&&"defaultStyles",o),style:n,id:"shiki-container"},l&&e?y.createElement("span",{className:x("languageLabel",a),style:h,id:"language-label"},e):null,g)};export{v as default,H as isInlineCode,S as rehypeInlineCodeProperty,p as useShikiHighlighter};
function h(e,{insertAt:i}={}){if(!e||typeof document>"u")return;let r=document.head||document.getElementsByTagName("head")[0],t=document.createElement("style");t.type="text/css",i==="top"&&r.firstChild?r.insertBefore(t,r.firstChild):r.appendChild(t),t.styleSheet?t.styleSheet.cssText=e:t.appendChild(document.createTextNode(e))}h(`.relative{position:relative}.defaultStyles pre{overflow:auto;border-radius:.5rem;padding:1.25rem 1.5rem}.languageLabel{position:absolute;right:.75rem;top:.5rem;font-family:monospace;font-size:.75rem;letter-spacing:-.05em;color:#6b7280d9}
`);import x from"react";import{clsx as S}from"clsx";import{useEffect as E,useRef as I,useState as v}from"react";import R from"html-react-parser";import{createHighlighter as N,createSingletonShorthands as P}from"shiki";import{visit as L}from"unist-util-visit";import{bundledLanguages as b,isSpecialLang as H}from"shiki";function C(){return function(e){L(e,"element",function(i,r,t){i.tagName==="code"&&t.tagName!=="pre"&&(i.properties.inline=!0)})}}var k=e=>!(e.children||[]).filter(r=>r.type==="text").map(r=>r.value).join("").includes(`
`),c={pre(e){return"properties"in e&&(e.properties.tabindex="-1"),e}},f=(e,i,r)=>{let t=Date.now();clearTimeout(i.current.timeoutId);let o=Math.max(0,i.current.nextAllowedTime-t);i.current.timeoutId=setTimeout(()=>{e().catch(console.error),i.current.nextAllowedTime=t+r},o)},y=e=>typeof e=="string"&&!(e in b)&&!H(e)?"plaintext":e;var w=P(N),u=(e,i,r,t={})=>{let[o,m]=v(null),p=y(i),n=I({nextAllowedTime:0,timeoutId:void 0});return E(()=>{let a=!0,g=[c,...t.transformers||[]],s=async()=>{let d=await w.codeToHtml(e,{lang:p,theme:r,transformers:g});a&&m(R(d))},{delay:l}=t;return l?f(s,n,l):s().catch(console.error),()=>{a=!1,clearTimeout(n.current.timeoutId)}},[e,i]),o};var B=({language:e,theme:i,delay:r,transformers:t,addDefaultStyles:o=!0,style:m,langStyle:p,className:n,langClassName:a,showLanguage:g=!0,children:s,as:l="pre"})=>{let T=u(s,e,i,{delay:r,transformers:t});return x.createElement(l,{"data-testid":"shiki-container",className:S("relative","not-prose",o&&"defaultStyles",n),style:m,id:"shiki-container"},g&&e?x.createElement("span",{className:S("languageLabel",a),style:p,id:"language-label"},e):null,T)};export{B as default,k as isInlineCode,C as rehypeInlineCodeProperty,u as useShikiHighlighter};
//# sourceMappingURL=index.js.map

2

package.json
{
"name": "react-shiki",
"description": "Syntax highlighter component for react using shiki",
"version": "0.2.4",
"version": "0.3.0",
"license": "MIT",

@@ -6,0 +6,0 @@ "author": {

@@ -21,2 +21,3 @@ # 🎨 [react-shiki](https://npmjs.com/react-shiki)

- [Custom themes](#custom-themes)
- [Custom transformers](#custom-transformers)
- [Performance](#performance)

@@ -32,4 +33,5 @@ - [Throttling real-time highlighting](#throttling-real-time-highlighting)

- 🔐 No `dangerouslySetInnerHTML`, output from Shiki is parsed using `html-react-parser`
- 📦 Supports all Shiki languages and themes in addition to
- 📦 Supports all Shiki languages and themes
- 🖌️ Full support for custom TextMate themes in a JavaScript object format
- 🔧 Supports passing custom Shiki transformers to the highlighter
- 🚰 Performant highlighting of streamed code on the client, with optional throttling

@@ -141,3 +143,3 @@ - 📚 Includes minimal default styles for code blocks

<ShikiHighlighter language={language} theme={"houston"} {...props}>
{String(children)}
{String(children).trim()}
</ShikiHighlighter>;

@@ -173,3 +175,3 @@ };

<ShikiHighlighter language={language} theme={"houston"} {...props}>
{String(children)}
{String(children).trim()}
</ShikiHighlighter>

@@ -217,3 +219,3 @@ ) : (

<ShikiHighlighter language={language} theme={"houston"} {...props}>
{String(children)}
{String(children).trim()}
</ShikiHighlighter>

@@ -229,3 +231,3 @@ ) : (

```tsx:title=CodeHighlight.tsx
```tsx
import tokyoNight from '@styles/tokyo-night.mjs';

@@ -238,2 +240,14 @@

### Custom transformers
```tsx
import { customTransformer } from '@utils/customTransformers';
<ShikiHighlighter
language="tsx"
transformers={[customTransformer]}>
{String(code).trim()}
</ShikiHighlighter>;
```
## Performance

@@ -258,8 +272,8 @@

I use it for an
LLM chatbot UI, it renders markdown and highlights code in memoized chat messages.
I use it for an LLM chatbot UI, it renders markdown and highlights
code in memoized chat messages.
Using `useShikiHighlighter` hook:
```tsx title=CodeHighlight.tsx
```tsx
import type { ReactNode } from "react";

@@ -281,3 +295,3 @@ import { isInlineCode, useShikiHighlighter, type Element } from "react-shiki";

}: CodeHighlightProps) => {
const code = String(children);
const code = String(children).trim();
const language = className?.match(/language-(\w+)/)?.[1];

@@ -316,3 +330,3 @@

```tsx title=CodeHighlight.tsx
```tsx
import type { ReactNode } from "react";

@@ -345,3 +359,3 @@ import ShikiHighlighter, { isInlineCode, type Element } from "react-shiki";

>
{String(children)}
{String(children).trim()}
</ShikiHighlighter>

@@ -358,3 +372,3 @@ ) : (

```tsx title=ChatMessages.tsx
```tsx
const RenderedMessage = React.memo(({ message }: { message: Message }) => (

@@ -361,0 +375,0 @@ <div className={cn(messageStyles[message.role])}>

Sorry, the diff of this file is not supported yet