Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
19 changes: 15 additions & 4 deletions apps/web/biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@
"enabled": true,
"indentStyle": "tab"
},
"assist": { "actions": { "source": { "organizeImports": "on" } } },
"assist": {
"actions": {
"source": {
"organizeImports": "on"
}
}
},
"linter": {
"enabled": true,
"rules": {
Expand All @@ -43,7 +49,8 @@
{
"includes": [
"**/components/dither-kit/**/*.tsx",
"**/routes/dither-kit.tsx"
"**/routes/dither-kit.tsx",
"**/components/dither-kit-docs/**/*.tsx"
],
"linter": {
"rules": {
Expand All @@ -54,7 +61,9 @@
}
},
{
"includes": ["**/components/icons/**/*.tsx"],
"includes": [
"**/components/icons/**/*.tsx"
],
"linter": {
"rules": {
"correctness": {
Expand All @@ -64,7 +73,9 @@
}
},
{
"includes": ["**/packages/ui/src/icons/**/*.tsx"],
"includes": [
"**/packages/ui/src/icons/**/*.tsx"
],
"linter": {
"rules": {
"correctness": {
Expand Down
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"clsx": "^2.1.1",
"d3-scale": "^4.0.2",
"d3-shape": "^3.2.0",
"dialkit": "^1.3.0",
"drizzle-kit": "^0.31.9",
"drizzle-orm": "^0.45.1",
"evlog": "^2.17.0",
Expand Down
178 changes: 178 additions & 0 deletions apps/web/src/components/dither-kit-docs/content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import type {
AreaVariant,
BloomInput,
ChartConfig,
} from "#/components/dither-kit"

/** Everything the dither-kit docs page renders from: install commands, demo
* data, the tweak model, and the live code snippets. */

/** Where the registry lives once deployed. */
export const HOST = "https://tripwire.sh"

/* ------------------------------------------------------- package manager */

export const PMS = ["npm", "pnpm", "yarn", "bun"] as const
export type Pm = (typeof PMS)[number]

/** The runner each package manager uses for one-off CLIs. */
const PM_RUNNER: Record<Pm, string> = {
npm: "npx",
pnpm: "pnpm dlx",
yarn: "yarn dlx",
bun: "bunx --bun",
}

export const addCmd = (pm: Pm, item: string): string =>
`${PM_RUNNER[pm]} shadcn@latest add ${item}`

/* ------------------------------------------------------------------ data */

const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug"]
export const series = MONTHS.map((month, i) => ({
month,
desktop: Math.round(120 + 90 * Math.sin(i * 0.7) + i * 14),
mobile: Math.round(70 + 50 * Math.cos(i * 0.5) + i * 8),
}))
export const config: ChartConfig = {
desktop: { label: "Desktop", color: "blue" },
mobile: { label: "Mobile", color: "purple" },
}
export const pieData = [
{ browser: "chrome", visitors: 275 },
{ browser: "safari", visitors: 200 },
{ browser: "firefox", visitors: 187 },
{ browser: "edge", visitors: 120 },
{ browser: "other", visitors: 90 },
]
export const pieConfig: ChartConfig = {
chrome: { label: "Chrome", color: "blue" },
safari: { label: "Safari", color: "green" },
firefox: { label: "Firefox", color: "orange" },
edge: { label: "Edge", color: "purple" },
other: { label: "Other", color: "grey" },
}
export const radarData = [
{ skill: "Speed", desktop: 186, mobile: 120 },
{ skill: "Power", desktop: 205, mobile: 98 },
{ skill: "Range", desktop: 137, mobile: 160 },
{ skill: "Defense", desktop: 173, mobile: 125 },
{ skill: "Magic", desktop: 160, mobile: 190 },
{ skill: "Luck", desktop: 144, mobile: 110 },
]

/* ---------------------------------------------------------- live tweaks */

export const VARIANTS: AreaVariant[] = [
"gradient",
"dotted",
"hatched",
"solid",
]
export const BLOOM_PRESETS = ["off", "low", "high", "aura", "custom"] as const
export type BloomPreset = (typeof BLOOM_PRESETS)[number]

export type Tweaks = {
bloomPreset: BloomPreset
blur: number
brightness: number
opacity: number
saturate: number
primaryVariant: AreaVariant
secondaryVariant: AreaVariant
stacked: boolean
donutRadius: number // 0 = full pie
duration: number // entrance ms
}

export function bloomOf(t: Tweaks): BloomInput {
return t.bloomPreset === "custom"
? {
blur: t.blur,
brightness: t.brightness,
opacity: t.opacity,
saturate: t.saturate,
}
: t.bloomPreset
}

/* ------------------------------------------------------------- snippets */

/** How the current bloom reads in the code snippets. */
function bloomAttr(t: Tweaks): string {
if (t.bloomPreset === "custom") {
return ` bloom={{ blur: ${t.blur}, brightness: ${t.brightness}, opacity: ${t.opacity}, saturate: ${t.saturate} }}`
}
return t.bloomPreset === "off" ? "" : ` bloom="${t.bloomPreset}"`
}

const stackAttr = (t: Tweaks): string =>
t.stacked ? ' stackType="stacked"' : ""

/** Non-default entrance timing shows up in the copied code too. */
const durationAttr = (t: Tweaks): string =>
t.duration === 900 ? "" : ` animationDuration={${t.duration}}`
Comment on lines +113 to +114

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## content.ts context\n'
sed -n '90,140p' apps/web/src/components/dither-kit-docs/content.ts | cat -n

printf '\n## dither-kit.tsx context\n'
sed -n '1,220p' apps/web/src/routes/dither-kit.tsx | cat -n

printf '\n## search for entranceMs and 900 defaults\n'
rg -n "entranceMs|900" apps/web/src/components/dither-kit-docs/content.ts apps/web/src/routes/dither-kit.tsx

Repository: bountydotnew/tripwire

Length of output: 7403


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## content.ts outline\n'
ast-grep outline apps/web/src/components/dither-kit-docs/content.ts --view expanded || true

printf '\n## dither-kit.tsx outline\n'
ast-grep outline apps/web/src/routes/dither-kit.tsx --view expanded || true

Repository: bountydotnew/tripwire

Length of output: 751


Keep the entrance duration default in one place. apps/web/src/components/dither-kit-docs/content.ts and apps/web/src/routes/dither-kit.tsx both hardcode 900, so the generated snippet can drift from the live default. Extract a shared DEFAULT_ENTRANCE_MS and use it in both spots.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/src/components/dither-kit-docs/content.ts` around lines 113 - 114,
The entrance duration default is hardcoded in both the docs snippet generator
and the live route, which can cause them to drift. Extract a shared
DEFAULT_ENTRANCE_MS constant and use it in content.ts’s durationAttr helper and
in the dither-kit route’s default value so both references stay synchronized.


export const areaCode = (t: Tweaks): string =>
`<AreaChart data={data} config={config}${stackAttr(t)}${bloomAttr(t)}${durationAttr(t)}>
<XAxis dataKey="month" />
<YAxis />
<Legend isClickable />
<Tooltip labelKey="month" />
<Area dataKey="desktop" variant="${t.primaryVariant}" />
<Area dataKey="mobile" variant="${t.secondaryVariant}" />
</AreaChart>`

export const barCode = (t: Tweaks): string =>
`<BarChart data={data} config={config}${stackAttr(t)}${bloomAttr(t)}${durationAttr(t)}>
<XAxis dataKey="month" />
<YAxis />
<Legend isClickable />
<Tooltip labelKey="month" />
<Bar dataKey="desktop" variant="${t.primaryVariant}" />
<Bar dataKey="mobile" variant="${t.secondaryVariant}" />
</BarChart>`

export const lineCode = (t: Tweaks): string =>
`// LineChart ships in the area-chart item (line = area + glow)
<LineChart data={data} config={config}${bloomAttr(t)}${durationAttr(t)}>
<XAxis dataKey="month" />
<YAxis />
<Legend isClickable />
<Tooltip labelKey="month" />
<Line dataKey="desktop" />
<Line dataKey="mobile" strokeVariant="dashed" />
</LineChart>`

export const pieCode = (t: Tweaks): string =>
`<PieChart data={data} config={config}
dataKey="visitors" nameKey="browser"${
t.donutRadius > 0 ? ` innerRadius={${t.donutRadius}}` : ""
}${bloomAttr(t)}${durationAttr(t)}>
<Legend isClickable align="center" />
<Tooltip />
<Pie variant="${t.primaryVariant}" />
</PieChart>`

export const radarCode = (t: Tweaks): string =>
`<RadarChart data={data} config={config} nameKey="skill"${bloomAttr(t)}${durationAttr(t)}>
<Legend isClickable align="center" />
<Tooltip />
<Radar dataKey="desktop" variant="${t.primaryVariant}" />
<Radar dataKey="mobile" variant="${t.secondaryVariant}" />
</RadarChart>`

export const PROPS: [string, string][] = [
["variant", '"gradient" | "dotted" | "hatched" | "solid"'],
[
"bloom",
'"off" | "low" | "high" | "aura" | { blur, brightness, opacity, saturate }',
],
["stackType", '"default" | "stacked" | "percent"'],
["colors", "green blue purple pink orange red grey"],
["animate", "animationDuration + replayToken for entrance and replay"],
["interactive", "false = decorative spark, no crosshair or tooltip"],
]

export const SPARKLINE_CODE = `// tiny decorative spark — no axes, no tooltip
<Sparkline data={[3, 7, 5, 9, 8, 12]} color="green" bloom="aura" />`
Loading
Loading