Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"@vitest/coverage-v8": "^3.2.4"
},
"peerDependencies": {
"react": "^19.1.0"
"react": "^19"
},
"dependencies": {
"@heroicons/react": "^2.2.0",
Expand Down
58 changes: 58 additions & 0 deletions src/CodeBlock/CodeBlock.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@ const meta = {
control: "select",
options: [...highlightLanguages],
},
kind: {
control: "select",
options: ["snippet", "file"],
},
code: { control: "text" },
allowCopy: { control: "boolean" },
},
args: {
kind: "snippet",
},
} satisfies Meta<typeof CodeBlock>;

export default meta;
Expand Down Expand Up @@ -55,3 +62,54 @@ jobs:
allowCopy: true,
},
};
export const GithubCI: Story = {
args: {
language: "yaml",
code: `on:
pull_request:
workflow_dispatch:
push:
branches:
- main

jobs:
nix-ci:
runs-on: ubuntu-latest
# Include this block to log in to FlakeHub and access private flakes
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: DeterminateSystems/determinate-nix-action@v3
- uses: DeterminateSystems/flakehub-cache-action@main
- uses: DeterminateSystems/nix-flake-checker-action@main
- run: nix flake check`,
title: ".github/workflows/nix-ci.yaml",
kind: "file",
allowCopy: true,
allowDownload: true,
},
};

export const AWS: Story = {
args: {
language: "terraform",
code: `data "aws_ami" "detsys_nixos" {
owners = ["535002876703"]
most_recent = true

filter {
name = "name"
values = ["determinate/nixos/epoch-1/*"]
}

filter {
name = "architecture"
values = ["x86_64"] # or "ARM64" for Graviton
}
}`,
title: "aws_ami.tf",
kind: "file",
},
};
33 changes: 32 additions & 1 deletion src/CodeBlock/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,38 @@

@use "../sass/mixins";
@use "../sass/tokens";
@use "../sass/functions";

.code-block {
@include mixins.border(base);
@include mixins.margin-y(xl);

.highlight {
@include mixins.border-bottom(base);
@include mixins.pad(base);
}
}

.code-block__heading {
@include mixins.pad-bottom(lg);
@include mixins.border-top(base);

padding: map.get(tokens.$spacing, base) map.get(tokens.$spacing, lg);
text-align: center;
align-items: center;
justify-content: space-between;
display: flex;

@include mixins.light-mode {
color: map.get(tokens.$brand, black);
}

background: functions.lighten(map.get(tokens.$brand, black), 5%);
@include mixins.light-mode {
background: functions.darken(map.get(tokens.$brand, white), 5%);
}
background-repeat: no-repeat;

.code-block__title--file {
font-family: map.get(tokens.$fonts, mono);
}
}
47 changes: 39 additions & 8 deletions src/CodeBlock/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ import Highlight from "../Highlight";
import CopyButton from "../CopyButton";

import "./index.scss";
import DownloadButton from "../DownloadButton";
import clsx from "clsx";

export interface CodeBlockProps {
language: HighlightLanguage;
code: string;
title: string;
downloadAs?: string;
allowCopy?: boolean;
allowDownload?: boolean;
kind: "snippet" | "file";
}
Comment on lines +18 to 19
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Make kind optional for backward compatibility

You already default kind to "snippet"; let callers omit it.

-  kind: "snippet" | "file";
+  kind?: "snippet" | "file";

Also ensure the exported type mirrors this change.

Also applies to: 24-33


🏁 Script executed:

#!/bin/bash
# Verify external exports and callsites for kind
rg -nP 'export\s+(type|interface)\s+CodeBlockProps' src/index.ts
rg -nP --type=tsx '<CodeBlock(?![^>]*\bkind=)' -C1

Length of output: 83


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "PWD: $(pwd)"
echo "=== List src/CodeBlock ==="
ls -la src/CodeBlock 2>/dev/null || echo "src/CodeBlock does not exist"

echo
echo "=== Show src/CodeBlock/index.tsx (first 240 lines) ==="
if [[ -f src/CodeBlock/index.tsx ]]; then
  sed -n '1,240p' src/CodeBlock/index.tsx | nl -ba -v1
else
  echo "MISSING: src/CodeBlock/index.tsx"
fi

echo
echo "=== Search for CodeBlockProps occurrences ==="
rg -n --hidden -S "CodeBlockProps" src || true

echo
echo "=== Search for 'export type|interface CodeBlockProps' ==="
rg -n --hidden -S "export\s+(type|interface)\s+CodeBlockProps" src || true

echo
echo "=== Search for 'kind:' definitions ==="
rg -n --hidden -S "kind\s*:" src || true

echo
echo "=== Find files with <CodeBlock and show context (3 lines) ==="
rg -n --hidden -S "<CodeBlock" -g 'src/**' -C3 || true

echo
echo "=== For each file containing <CodeBlock, check if file contains 'kind=' anywhere ==="
files=$(rg -n --hidden -S "<CodeBlock" -g 'src/**' --files || true)
if [[ -z "${files// /}" ]]; then
  echo "No files with <CodeBlock found under src/"
else
  for f in $files; do
    echo "---- File: $f ----"
    rg -n --hidden -S "<CodeBlock" -n -C3 "$f" || true
    echo "---- 'kind=' occurrences in $f ----"
    rg -n --hidden -S "kind\s*=" -n -C3 "$f" || echo "no kind= in $f"
  done
fi

Length of output: 455


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "PWD: $(pwd)"
echo

echo "=== Show src/CodeBlock/index.tsx ==="
if [[ -f src/CodeBlock/index.tsx ]]; then
  sed -n '1,400p' src/CodeBlock/index.tsx || true
else
  echo "MISSING: src/CodeBlock/index.tsx"
fi

echo
echo "=== Search for CodeBlockProps occurrences ==="
rg -n --hidden --no-ignore "CodeBlockProps" src || true

echo
echo "=== Search for explicit exports of CodeBlockProps ==="
rg -n --hidden --no-ignore "export type CodeBlockProps" src || true
rg -n --hidden --no-ignore "export interface CodeBlockProps" src || true

echo
echo "=== Search for 'kind' property definitions/usages ==="
rg -n --hidden --no-ignore "kind\s*:" src || true
rg -n --hidden --no-ignore "\"snippet\"\s*\|\s*\"file\"" src || true

echo
echo "=== Find <CodeBlock components and whether they pass kind= ==="
rg -n --hidden --no-ignore "<CodeBlock" -g 'src/**' -C2 || true
files=$(rg --hidden --no-ignore "<CodeBlock" -g 'src/**' --files || true)
if [[ -z "${files// /}" ]]; then
  echo "No files with <CodeBlock found under src/"
else
  for f in $files; do
    echo
    echo "---- File: $f ----"
    sed -n '1,200p' "$f" || true
    echo "---- 'kind=' occurrences in $f ----"
    rg -n --hidden --no-ignore "kind\s*=" -n -C2 "$f" || echo "no kind= in $f"
  done
fi

Length of output: 5026


Make CodeBlockProps.kind optional

Align the exported type with the component default and existing call sites.

-  kind: "snippet" | "file";
+  kind?: "snippet" | "file";

Edit: src/CodeBlock/index.tsx (interface CodeBlockProps — kind at ~line 18). src/index.ts re-exports the type — no change needed.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
kind: "snippet" | "file";
}
kind?: "snippet" | "file";
}
🤖 Prompt for AI Agents
In src/CodeBlock/index.tsx around lines 18-19, the CodeBlockProps.interface
marks kind as required but the component and existing callers treat it as
optional; change the interface to make kind optional (kind?: "snippet" |
"file"), leaving any re-exports unchanged, and run typecheck to ensure no other
call sites need updates.


/**
Expand All @@ -20,14 +25,40 @@ const CodeBlock: FC<CodeBlockProps> = ({
language,
code,
title,
downloadAs = title,
allowDownload = true,
allowCopy = true,
}) => (
<figure className="code-block" aria-label={title}>
<figcaption className="code-block__heading">
{title} {allowCopy && <CopyButton data={code} />}
</figcaption>
<Highlight language={language} code={code} />
</figure>
);
kind = "snippet",
}) => {
const trimmedCode = code.trim();
const isFile = kind === "file";

return (
<figure className="code-block" aria-label={title}>
<figcaption className="code-block__heading">
<span
className={clsx(
"code-block__title",
isFile && "code-block__title--file",
)}
>
{title}
</span>
{(allowCopy || allowDownload) && (
<span className="code-block__icons">
{allowCopy && <CopyButton data={trimmedCode} />}
{allowDownload && isFile && (
<DownloadButton
data={trimmedCode}
filename={downloadAs.split("/").reverse()[0]}
/>
)}
</span>
)}
</figcaption>
<Highlight language={language} code={trimmedCode} />
</figure>
);
};

export default CodeBlock;
75 changes: 0 additions & 75 deletions src/CodeFile/CodeFile.stories.tsx

This file was deleted.

12 changes: 0 additions & 12 deletions src/CodeFile/index.scss

This file was deleted.

56 changes: 0 additions & 56 deletions src/CodeFile/index.tsx

This file was deleted.

21 changes: 18 additions & 3 deletions src/ColorProvider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,15 @@ const ColorProvider: React.FC<PropsWithChildren<ColorProviderProps>> = ({
useLocalStorage = true,
simulatedSystemColorScheme,
preferredColorScheme,
root = document.body,
root,
children,
}) => {
if (!root) {
if (typeof document !== "undefined") {
root = document.body;
}
}

const actualSystemColorScheme = useSystemColorScheme();
const systemColorScheme =
simulatedSystemColorScheme ?? actualSystemColorScheme;
Expand All @@ -109,7 +115,9 @@ const ColorProvider: React.FC<PropsWithChildren<ColorProviderProps>> = ({
);

// Apply the theme super early so we don't get a FOUC
applyTheme(root, scheme);
if (root) {
applyTheme(root, scheme);
}

// Since we're pretty high up in the component tree, we want to be extremely
// careful about re-rendering. Memoization ensures that the object only
Expand All @@ -127,7 +135,9 @@ const ColorProvider: React.FC<PropsWithChildren<ColorProviderProps>> = ({

// Switch body classes depending on the chosen scheme
useEffect(() => {
applyTheme(root, scheme);
if (root) {
applyTheme(root, scheme);
}
}, [scheme]);

return (
Expand All @@ -137,6 +147,11 @@ const ColorProvider: React.FC<PropsWithChildren<ColorProviderProps>> = ({

function applyTheme(root: Element, scheme: ColorScheme) {
const classes = root.classList;
if (classes === undefined) {
console.log("classList on the root is null... probably SSR?");
return;
}

const [next, previous] =
scheme === "light" ? ["light", "dark"] : ["dark", "light"];

Expand Down
Loading