1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2026-01-12 06:42:56 -05:00

add language indicator to code blocks

This commit is contained in:
2025-05-07 20:01:12 -04:00
parent 6fd7c9fc4a
commit fff705f1e8
15 changed files with 90 additions and 59 deletions

View File

@@ -176,7 +176,5 @@
} }
@layer components { @layer components {
.youtube-embed { @import "react-lite-youtube-embed/dist/LiteYouTubeEmbed.css";
@import "react-lite-youtube-embed/dist/LiteYouTubeEmbed.css";
}
} }

View File

@@ -11,9 +11,9 @@ export const metadata = createMetadata({
export const WarningMarquee = () => ( export const WarningMarquee = () => (
<Marquee> <Marquee>
<span> <span className="leading-none select-none">
🚨 Trigger warning: excessive marquees, animated GIFs, Comic Sans, popups,{" "} 🚨 Trigger warning: excessive marquees, animated GIFs, Comic Sans, popups,{" "}
<code style={{ fontWeight: "normal", fontSize: "0.9em" }}> <code className="text-[0.9rem] font-normal">
color: <span style={{ color: "#32cd32" }}>limegreen</span> color: <span style={{ color: "#32cd32" }}>limegreen</span>
</code>{" "} </code>{" "}
ahead... ahead...
@@ -23,7 +23,8 @@ export const WarningMarquee = () => (
export const PageStyles = () => ( export const PageStyles = () => (
<style> <style>
{`body { {`
body {
cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAZklEQVR4AWIAgn/uBT6A9uoAAwAQiIJo97/0Rgy0ANoJH8MPeEgtqwPQEACqCoQHAKECQKgAECoAhAoAoQJAqAAQxh1oPQfcW3kJpxHtL1AAHAwEwwdYiH8BIEgBTBRAAAEEEEAAG7mRt30hEhoLAAAAAElFTkSuQmCC") 2 1, auto; cursor: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAZklEQVR4AWIAgn/uBT6A9uoAAwAQiIJo97/0Rgy0ANoJH8MPeEgtqwPQEACqCoQHAKECQKgAECoAhAoAoQJAqAAQxh1oPQfcW3kJpxHtL1AAHAwEwwdYiH8BIEgBTBRAAAEEEEAAG7mRt30hEhoLAAAAAElFTkSuQmCC") 2 1, auto;
} }
a, button { a, button {
@@ -78,8 +79,7 @@ _Previously on the [Cringey Chronicles&trade;](https://web.archive.org/web/20010
<iframe <iframe
src="https://jakejarvis.github.io/my-first-website/" src="https://jakejarvis.github.io/my-first-website/"
title="My Terrible, Horrible, No Good, Very Bad First Website" title="My Terrible, Horrible, No Good, Very Bad First Website"
className="border-ring w-full border-2" className="border-ring h-[500px] w-full border-2"
style={{ height: "500px" }}
/> />
_[November 2001](https://jakejarvis.github.io/my-first-website/) ([view _[November 2001](https://jakejarvis.github.io/my-first-website/) ([view
source](https://github.com/jakejarvis/my-first-website))_ source](https://github.com/jakejarvis/my-first-website))_

View File

@@ -14,9 +14,7 @@ export const Terminal = () => (
<div <div
className="relative mx-auto my-6 w-full rounded-lg" className="relative mx-auto my-6 w-full rounded-lg"
style={{ style={{
backgroundImage: `url(${backgroundImg.src})`, background: `url(${backgroundImg.src}) center no-repeat`,
backgroundRepeat: "repeat",
backgroundPosition: "center",
}} }}
> >
<code className="border-ring block rounded-lg border border-solid bg-black/60 p-4 text-sm break-all text-white/90 backdrop-blur-xs backdrop-saturate-150"> <code className="border-ring block rounded-lg border border-solid bg-black/60 p-4 text-sm break-all text-white/90 backdrop-blur-xs backdrop-saturate-150">

View File

@@ -1,16 +1,19 @@
import { codeToHtml } from "shiki"; import { codeToHtml } from "shiki";
import reactToText from "react-to-text"; import reactToText from "react-to-text";
import { CodeIcon } from "lucide-react";
import CopyButton from "@/components/copy-button"; import CopyButton from "@/components/copy-button";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import type { ComponentProps, ComponentPropsWithoutRef } from "react"; import type { ComponentProps, ComponentPropsWithoutRef } from "react";
const CodeBlock = async ({ const CodeBlock = async ({
lineNumbers = false, showLineNumbers = false,
showCopyButton = true,
className, className,
children, children,
...rest ...rest
}: ComponentPropsWithoutRef<"pre"> & { }: ComponentPropsWithoutRef<"pre"> & {
lineNumbers?: boolean; showLineNumbers?: boolean;
showCopyButton?: boolean;
}) => { }) => {
// escape hatch if this code wasn't meant to be highlighted // escape hatch if this code wasn't meant to be highlighted
if (!children || typeof children !== "object" || !("props" in children)) { if (!children || typeof children !== "object" || !("props" in children)) {
@@ -35,22 +38,57 @@ const CodeBlock = async ({
}, },
}); });
const getFullLang = (lang: string) => {
// replace the file extension with the full language name when it makes sense to
switch (lang.toLowerCase()) {
case "js":
return "JavaScript";
case "jsx":
return "JavaScript (JSX)";
case "ts":
return "TypeScript";
case "tsx":
return "TypeScript (JSX)";
case "sh":
case "bash":
case "zsh":
return "Shell";
case "py":
return "Python";
case "md":
return "Markdown";
case "mdx":
return "Markdown (MDX)";
default:
return lang;
}
};
const fullLang = getFullLang(lang);
return ( return (
<div className={cn("bg-muted/35 relative isolate rounded-lg border-2 font-mono", className)}> <div className={cn("bg-muted/35 relative isolate rounded-lg border-2 font-mono", className)}>
<div <div
className={cn( className={cn(
"grid max-h-[500px] w-full overflow-x-auto p-4 **:bg-transparent! md:max-h-[650px] dark:**:text-[var(--shiki-dark)]! [&_pre]:whitespace-normal", "grid max-h-[500px] w-full overflow-x-auto p-4 **:bg-transparent! data-language:pt-9 md:max-h-[650px] dark:**:text-[var(--shiki-dark)]! [&_pre]:whitespace-normal",
"[&_.line]:inline-block [&_.line]:min-w-full [&_.line]:py-1 [&_.line]:leading-none [&_.line]:whitespace-pre [&_.line]:after:hidden", "[&_.line]:inline-block [&_.line]:min-w-full [&_.line]:py-1 [&_.line]:leading-none [&_.line]:whitespace-pre [&_.line]:after:hidden",
"data-line-numbers:[&_.line]:before:text-muted-foreground data-line-numbers:[counter-reset:line] data-line-numbers:[&_.line]:[counter-increment:line] data-line-numbers:[&_.line]:before:mr-5 data-line-numbers:[&_.line]:before:inline-block data-line-numbers:[&_.line]:before:w-5 data-line-numbers:[&_.line]:before:text-right data-line-numbers:[&_.line]:before:content-[counter(line)]" "data-line-numbers:[&_.line]:before:text-muted-foreground data-line-numbers:[counter-reset:line] data-line-numbers:[&_.line]:[counter-increment:line] data-line-numbers:[&_.line]:before:mr-5 data-line-numbers:[&_.line]:before:inline-block data-line-numbers:[&_.line]:before:w-5 data-line-numbers:[&_.line]:before:text-right data-line-numbers:[&_.line]:before:content-[counter(line)]"
)} )}
data-language={lang} data-language={lang || undefined}
data-line-numbers={lineNumbers || undefined} data-line-numbers={showLineNumbers || undefined}
dangerouslySetInnerHTML={{ __html: codeHighlighted }} dangerouslySetInnerHTML={{ __html: codeHighlighted }}
/> />
<CopyButton {fullLang && (
source={codeString} <span className="text-foreground/75 bg-muted/40 absolute top-0 left-0 flex items-center rounded-tl-md rounded-br-lg border-r-2 border-b-2 py-[5px] pr-[10px] font-mono text-xs font-medium tracking-wide uppercase backdrop-blur-xs select-none">
className="text-foreground/85 hover:text-primary bg-muted/10 absolute top-0 right-0 size-10 rounded-tr-lg rounded-bl-lg border-b-2 border-l-2 p-0 backdrop-blur-xs [&_svg]:my-auto [&_svg]:inline-block [&_svg]:size-4.5 [&_svg]:align-text-bottom" <CodeIcon className="stroke-primary/90 mr-[8px] ml-[10px] inline-block size-[14px]" /> <span>{fullLang}</span>
/> </span>
)}
{showCopyButton && (
<CopyButton
source={codeString}
className="text-foreground/75 hover:text-primary bg-muted/40 absolute top-0 right-0 size-10 rounded-tr-md rounded-bl-lg border-b-2 border-l-2 p-0 backdrop-blur-xs select-none [&_svg]:my-auto [&_svg]:inline-block [&_svg]:size-4.5 [&_svg]:align-text-bottom"
/>
)}
</div> </div>
); );
}; };

View File

@@ -3,13 +3,14 @@
import { forwardRef, useState, useEffect } from "react"; import { forwardRef, useState, useEffect } from "react";
import copy from "copy-to-clipboard"; import copy from "copy-to-clipboard";
import { ClipboardIcon, CheckIcon } from "lucide-react"; import { ClipboardIcon, CheckIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import type { Ref, ComponentPropsWithoutRef, ComponentRef, MouseEventHandler } from "react"; import type { Ref, ComponentPropsWithoutRef, ComponentRef, MouseEventHandler } from "react";
const CopyButton = ( const CopyButton = (
{ {
source, source,
timeout = 2000, timeout = 2000,
style, className,
...rest ...rest
}: ComponentPropsWithoutRef<"button"> & { }: ComponentPropsWithoutRef<"button"> & {
source: string; source: string;
@@ -51,7 +52,7 @@ const CopyButton = (
ref={ref} ref={ref}
onClick={handleCopy} onClick={handleCopy}
disabled={copied} disabled={copied}
style={{ cursor: copied ? "default" : "pointer", ...style }} className={cn("cursor-pointer disabled:cursor-default", className)}
{...rest} {...rest}
> >
{copied ? <CheckIcon className="stroke-success" /> : <ClipboardIcon />} {copied ? <CheckIcon className="stroke-success" /> : <ClipboardIcon />}

View File

@@ -3,15 +3,10 @@
import YouTubeEmbed from "react-lite-youtube-embed"; import YouTubeEmbed from "react-lite-youtube-embed";
import type { ComponentPropsWithoutRef } from "react"; import type { ComponentPropsWithoutRef } from "react";
// lite-youtube-embed CSS is imported in app/global.css to save a request
const YouTube = ({ ...rest }: Omit<ComponentPropsWithoutRef<typeof YouTubeEmbed>, "title">) => { const YouTube = ({ ...rest }: Omit<ComponentPropsWithoutRef<typeof YouTubeEmbed>, "title">) => {
return ( return <YouTubeEmbed cookie={false} containerElement="div" title="" {...rest} />;
<div
// lite-youtube-embed CSS is imported in app/global.css to save a request
className="youtube-embed"
>
<YouTubeEmbed cookie={false} containerElement="div" title="" {...rest} />
</div>
);
}; };
export default YouTube; export default YouTube;

View File

@@ -127,9 +127,12 @@ export const getViews: {
slug?: any slug?: any
): // eslint-disable-next-line @typescript-eslint/no-explicit-any ): // eslint-disable-next-line @typescript-eslint/no-explicit-any
Promise<any> => { Promise<any> => {
// ensure the prefix is consistent for all keys in the KV store
const KEY_PREFIX = `hits:${POSTS_DIR}/`;
if (typeof slug === "string") { if (typeof slug === "string") {
try { try {
const views = await kv.get<string>(`hits:${POSTS_DIR}/${slug}`); const views = await kv.get<string>(`${KEY_PREFIX}${slug}`);
return views ? parseInt(views, 10) : undefined; return views ? parseInt(views, 10) : undefined;
} catch (error) { } catch (error) {
@@ -144,12 +147,10 @@ export const getViews: {
const pages: Record<string, number> = {}; const pages: Record<string, number> = {};
// get the value (number of views) for each key (the slug of the page) // get the value (number of views) for each key (the slug of the page)
const values = await kv.mget<string[]>(...allSlugs.map((slug) => `hits:${POSTS_DIR}/${slug}`)); const values = await kv.mget<string[]>(...allSlugs.map((slug) => `${KEY_PREFIX}${slug}`));
// pair the slugs with their view counts // pair the slugs with their view counts
allSlugs.forEach( allSlugs.forEach((slug, index) => (pages[slug.replace(KEY_PREFIX, "")] = parseInt(values[index], 10)));
(slug, index) => (pages[slug.replace(`hits:${POSTS_DIR}/`, "")] = parseInt(values[index], 10))
);
return pages; return pages;
} catch (error) { } catch (error) {

View File

@@ -72,7 +72,7 @@ export const useMDXComponents = (components: MDXComponents): MDXComponents => {
h3: ({ className, id, children, ...rest }) => ( h3: ({ className, id, children, ...rest }) => (
<h3 <h3
className={cn( className={cn(
"group mt-6 mb-2.5 scroll-m-4 text-lg leading-relaxed font-semibold md:text-xl [&_code]:text-[0.9em] [&_strong]:font-bold [&+*]:mt-0", "group mt-6 mb-4 scroll-m-4 text-lg leading-relaxed font-semibold md:text-xl [&_code]:text-[0.9em] [&_strong]:font-bold [&+*]:mt-0",
className className
)} )}
id={id} id={id}

View File

@@ -24,7 +24,7 @@ Below are the code snippets you can grab and customize to make your own ["waving
## CSS ## CSS
{/* prettier-ignore */} {/* prettier-ignore */}
```css lineNumbers ```css showLineNumbers
.wave { .wave {
animation-name: wave-animation; /* Refers to the name of your @keyframes element below */ animation-name: wave-animation; /* Refers to the name of your @keyframes element below */
animation-duration: 2.5s; /* Change to speed up or slow down */ animation-duration: 2.5s; /* Change to speed up or slow down */

View File

@@ -34,8 +34,7 @@ I've written a simple implementation below, which...
<iframe <iframe
src="https://jakejarvis.github.io/dark-mode-example/" src="https://jakejarvis.github.io/dark-mode-example/"
title="Dark Mode Example" title="Dark Mode Example"
className="border-ring w-full border-2" className="border-ring h-[190px] w-full border-2"
style={{ height: "190px" }}
></iframe> ></iframe>
A _very_ barebones example is embedded above ([view the source here](https://github.com/jakejarvis/dark-mode-example), or [open in a new window](https://jakejarvis.github.io/dark-mode-example/) if your browser is blocking the frame) and you can try it out on this site by clicking the 💡 lightbulb in the upper right corner of this page. You'll notice that the dark theme sticks when refreshing this page, navigating between other pages, or if you were to return to this example weeks from now. A _very_ barebones example is embedded above ([view the source here](https://github.com/jakejarvis/dark-mode-example), or [open in a new window](https://jakejarvis.github.io/dark-mode-example/) if your browser is blocking the frame) and you can try it out on this site by clicking the 💡 lightbulb in the upper right corner of this page. You'll notice that the dark theme sticks when refreshing this page, navigating between other pages, or if you were to return to this example weeks from now.
@@ -46,7 +45,7 @@ A _very_ barebones example is embedded above ([view the source here](https://git
I have cleaned up this code a bit, added a few features, and packaged it as an [📦 NPM module](https://www.npmjs.com/package/dark-mode-switcheroo) (zero dependencies and still [only ~500 bytes](https://bundlephobia.com/package/dark-mode-switcheroo) minified and gzipped!). Here's a small snippet of the updated method for the browser (pulling the module from [UNPKG](https://unpkg.com/browse/dark-mode-switcheroo/)), but definitely [read the readme](https://github.com/jakejarvis/dark-mode#readme) for much more detail on the API. I have cleaned up this code a bit, added a few features, and packaged it as an [📦 NPM module](https://www.npmjs.com/package/dark-mode-switcheroo) (zero dependencies and still [only ~500 bytes](https://bundlephobia.com/package/dark-mode-switcheroo) minified and gzipped!). Here's a small snippet of the updated method for the browser (pulling the module from [UNPKG](https://unpkg.com/browse/dark-mode-switcheroo/)), but definitely [read the readme](https://github.com/jakejarvis/dark-mode#readme) for much more detail on the API.
```html lineNumbers ```html showLineNumbers
<button class="dark-mode-toggle" style="visibility: hidden;">💡 Click to see the light... or not.</button> <button class="dark-mode-toggle" style="visibility: hidden;">💡 Click to see the light... or not.</button>
<script src="https://unpkg.com/dark-mode-switcheroo/dist/dark-mode.min.js"></script> <script src="https://unpkg.com/dark-mode-switcheroo/dist/dark-mode.min.js"></script>
@@ -94,7 +93,7 @@ The [example HTML and CSS below](#html-css) is still helpful for reference.
### Full JS: ### Full JS:
{/* prettier-ignore */} {/* prettier-ignore */}
```js lineNumbers ```js showLineNumbers
/*! Dark mode switcheroo | MIT License | jrvs.io/darkmode */ /*! Dark mode switcheroo | MIT License | jrvs.io/darkmode */
(function () { (function () {
@@ -177,7 +176,7 @@ The [example HTML and CSS below](#html-css) is still helpful for reference.
### HTML & CSS Example: ### HTML & CSS Example:
{/* prettier-ignore */} {/* prettier-ignore */}
```html lineNumbers ```html showLineNumbers
<!doctype html> <!doctype html>
<html> <html>
<head> <head>

View File

@@ -102,7 +102,7 @@ I removed the company's name because an important part of responsible _disclosur
The `poc-d4ca9e8ceb.html` proof-of-concept file contained this single, hidden line: The `poc-d4ca9e8ceb.html` proof-of-concept file contained this single, hidden line:
```html lineNumbers ```html showLineNumbers
<!-- subdomain takeover POC by @jakejarvis on Bugcrowd --> <!-- subdomain takeover POC by @jakejarvis on Bugcrowd -->
``` ```

View File

@@ -43,7 +43,7 @@ If you're bored on a rainy day, potential activities could include:
Who cares if somebody wants to delete a post with the ID "`*`" no matter the author? ([delete_reply_submit.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/delete_reply_submit.php#L9)) Who cares if somebody wants to delete a post with the ID "`*`" no matter the author? ([delete_reply_submit.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/delete_reply_submit.php#L9))
```php lineNumbers ```php showLineNumbers
<?php <?php
$query2 = "DELETE FROM jbb_replies $query2 = "DELETE FROM jbb_replies
WHERE replyID ='$replyID'"; WHERE replyID ='$replyID'";
@@ -54,7 +54,7 @@ $result2 = mysql_query ($query2)
Sessions based on storing an auto-incremented user ID in a cookie. ([login_submit.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/login_submit.php#L28)) Sessions based on storing an auto-incremented user ID in a cookie. ([login_submit.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/login_submit.php#L28))
```php lineNumbers ```php showLineNumbers
<?php <?php
session_id($user->userID); session_id($user->userID);
session_start(); session_start();
@@ -66,7 +66,7 @@ $_SESSION["ck_groupID"] = $user->groupID;
Viewing a "private" message based solely on a sequential message ID. ([pm_view.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/pm_view.php#L13)) Viewing a "private" message based solely on a sequential message ID. ([pm_view.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/pm_view.php#L13))
```php lineNumbers ```php showLineNumbers
<?php <?php
$query1 = "SELECT * FROM jbb_pm WHERE pmID = '$pmID'"; $query1 = "SELECT * FROM jbb_pm WHERE pmID = '$pmID'";
?> ?>
@@ -74,7 +74,7 @@ $query1 = "SELECT * FROM jbb_pm WHERE pmID = '$pmID'";
Incredibly ambitious emoticon and [BBCode](https://en.wikipedia.org/wiki/BBCode) support. I honestly can't begin to explain this logic. ([functions.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/functions.php#L18)) Incredibly ambitious emoticon and [BBCode](https://en.wikipedia.org/wiki/BBCode) support. I honestly can't begin to explain this logic. ([functions.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/functions.php#L18))
```php lineNumbers ```php showLineNumbers
<?php <?php
$replacement = '<img src=images/emoticons/smile.gif>'; $replacement = '<img src=images/emoticons/smile.gif>';
$replacement2 = '<img src=images/emoticons/bigsmile.gif>'; $replacement2 = '<img src=images/emoticons/bigsmile.gif>';
@@ -111,7 +111,7 @@ $topicval = str_replace('
Saving new passwords as plaintext — probably the least problematic problem. ([register_submit.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/register_submit.php#L10)) Saving new passwords as plaintext — probably the least problematic problem. ([register_submit.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/register_submit.php#L10))
```php lineNumbers ```php showLineNumbers
<?php <?php
$query = "INSERT INTO jbb_users (username, password, email, avatar) VALUES ('$username','$password','$email','images/avatars/noavatar.gif')"; $query = "INSERT INTO jbb_users (username, password, email, avatar) VALUES ('$username','$password','$email','images/avatars/noavatar.gif')";
?> ?>
@@ -119,7 +119,7 @@ $query = "INSERT INTO jbb_users (username, password, email, avatar) VALUES ('$us
I guess I gave up on counting `$query`s by ones... ([functions.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/functions.php#L231)) I guess I gave up on counting `$query`s by ones... ([functions.php](https://github.com/jakejarvis/jbb/blob/87b606797414b2fe563af85e269566fc5e076cc5/functions.php#L231))
```php lineNumbers ```php showLineNumbers
<?php <?php
while ($topic = mysql_fetch_object($result30)) { while ($topic = mysql_fetch_object($result30)) {
$query40 = "SELECT * FROM jbb_users WHERE userID = '$topic->userID'"; $query40 = "SELECT * FROM jbb_users WHERE userID = '$topic->userID'";

View File

@@ -28,7 +28,7 @@ If you run your own server, these can be added by way of your Apache or nginx co
The following script can be added as a Worker and customized to your needs. Some can be extremely picky with syntax, so be sure to [read the documentation](https://www.netsparker.com/whitepaper-http-security-headers/) carefully. You can fiddle with it in [the playground](https://cloudflareworkers.com/), too. Simply modify the current headers to your needs, or add new ones to the `newHeaders` or `removeHeaders` arrays. The following script can be added as a Worker and customized to your needs. Some can be extremely picky with syntax, so be sure to [read the documentation](https://www.netsparker.com/whitepaper-http-security-headers/) carefully. You can fiddle with it in [the playground](https://cloudflareworkers.com/), too. Simply modify the current headers to your needs, or add new ones to the `newHeaders` or `removeHeaders` arrays.
```js lineNumbers ```js showLineNumbers
let addHeaders = { let addHeaders = {
"Content-Security-Policy": "default-src 'self'; upgrade-insecure-requests", "Content-Security-Policy": "default-src 'self'; upgrade-insecure-requests",
"Strict-Transport-Security": "max-age=1000", "Strict-Transport-Security": "max-age=1000",

View File

@@ -86,7 +86,7 @@
"@jakejarvis/eslint-config": "^4.0.7", "@jakejarvis/eslint-config": "^4.0.7",
"@tailwindcss/postcss": "^4.1.5", "@tailwindcss/postcss": "^4.1.5",
"@types/mdx": "^2.0.13", "@types/mdx": "^2.0.13",
"@types/node": "^22.15.14", "@types/node": "^22.15.15",
"@types/prop-types": "^15.7.14", "@types/prop-types": "^15.7.14",
"@types/react": "^19.1.3", "@types/react": "^19.1.3",
"@types/react-dom": "^19.1.3", "@types/react-dom": "^19.1.3",
@@ -131,7 +131,8 @@
"pnpm": { "pnpm": {
"peerDependencyRules": { "peerDependencyRules": {
"allowedVersions": { "allowedVersions": {
"react": "^19" "react": "^19",
"react-dom": "^19"
} }
} }
} }

14
pnpm-lock.yaml generated
View File

@@ -208,8 +208,8 @@ importers:
specifier: ^2.0.13 specifier: ^2.0.13
version: 2.0.13 version: 2.0.13
'@types/node': '@types/node':
specifier: ^22.15.14 specifier: ^22.15.15
version: 22.15.14 version: 22.15.15
'@types/prop-types': '@types/prop-types':
specifier: ^15.7.14 specifier: ^15.7.14
version: 15.7.14 version: 15.7.14
@@ -1242,8 +1242,8 @@ packages:
'@types/nlcst@2.0.3': '@types/nlcst@2.0.3':
resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
'@types/node@22.15.14': '@types/node@22.15.15':
resolution: {integrity: sha512-BL1eyu/XWsFGTtDWOYULQEs4KR0qdtYfCxYAUYRoB7JP7h9ETYLgQTww6kH8Sj2C0pFGgrpM0XKv6/kbIzYJ1g==} resolution: {integrity: sha512-R5muMcZob3/Jjchn5LcO8jdKwSCbzqmPB6ruBxMcf9kbxtniZHP327s6C37iOfuw8mbKK3cAQa7sEl7afLrQ8A==}
'@types/prop-types@15.7.14': '@types/prop-types@15.7.14':
resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==}
@@ -5221,7 +5221,7 @@ snapshots:
'@types/concat-stream@2.0.3': '@types/concat-stream@2.0.3':
dependencies: dependencies:
'@types/node': 22.15.14 '@types/node': 22.15.15
'@types/debug@4.1.12': '@types/debug@4.1.12':
dependencies: dependencies:
@@ -5257,7 +5257,7 @@ snapshots:
dependencies: dependencies:
'@types/unist': 3.0.3 '@types/unist': 3.0.3
'@types/node@22.15.14': '@types/node@22.15.15':
dependencies: dependencies:
undici-types: 6.21.0 undici-types: 6.21.0
@@ -8799,7 +8799,7 @@ snapshots:
'@types/concat-stream': 2.0.3 '@types/concat-stream': 2.0.3
'@types/debug': 4.1.12 '@types/debug': 4.1.12
'@types/is-empty': 1.2.3 '@types/is-empty': 1.2.3
'@types/node': 22.15.14 '@types/node': 22.15.15
'@types/unist': 3.0.3 '@types/unist': 3.0.3
concat-stream: 2.0.0 concat-stream: 2.0.0
debug: 4.4.0 debug: 4.4.0