Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
34bf97b
refactor: restructure components and migrate shared Section.astro usa…
bryanlundberg Nov 1, 2025
4118a36
fix: disable `noDangerouslySetInnerHtml` rule and resolve unique key …
bryanlundberg Nov 1, 2025
11d398a
refactor: replace Astro components with React-based alternatives and …
bryanlundberg Nov 1, 2025
2b6ac29
chore: remove `noDangerouslySetInnerHtml` linter override and clean u…
bryanlundberg Nov 1, 2025
8887661
refactor: update ReactPanelContainer styles and improve resize handle…
bryanlundberg Nov 1, 2025
c653c10
refactor: introduce dynamic sizing hooks for responsiveness and impro…
bryanlundberg Nov 2, 2025
eeba009
chore: add `sharp` library to dependencies in package.json
bryanlundberg Nov 2, 2025
fc88b4e
refactor: extract collapsible panel logic into reusable component
ArturoAtomplay Nov 2, 2025
7a6bd86
Merge branch 'experimental-drag-react' of https://github.com/bryanlun…
ArturoAtomplay Nov 2, 2025
86a1652
refactor: implement panel collapsing logic with Zustand store and enh…
bryanlundberg Nov 2, 2025
c07a094
refactor: update ReactTerminal styling for border radius adjustment
bryanlundberg Nov 2, 2025
92e6e77
refactor: enhance gruvboxDarkTheme with improved styling and addition…
bryanlundberg Nov 2, 2025
a73cfe8
refactor: improve scrollbar styling for code editor with custom width…
bryanlundberg Nov 2, 2025
63be663
refactor: enhance editor layout and simplify ReactCodeEditor structure
bryanlundberg Nov 2, 2025
ed87e0d
refactor: implement Rust code execution feature with Zustand store in…
bryanlundberg Nov 2, 2025
69f42ee
refactor: integrate live compiler feedback and execution state into R…
bryanlundberg Nov 2, 2025
ab081f9
refactor: modularize ReactTerminal by extracting TerminalHeader and T…
bryanlundberg Nov 2, 2025
648ec90
refactor: introduce OutputVariant enum and update OutputLine for clea…
bryanlundberg Nov 2, 2025
4f4704d
refactor(content): simplify content management and navigation structure
ArturoAtomplay Nov 2, 2025
c39bfce
refactor: optimize client directive loading for content page
ArturoAtomplay Nov 3, 2025
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
11 changes: 11 additions & 0 deletions package-lock.json

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

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
"nanostores": "^1.0.1",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"tailwindcss": "^4.1.16"
"react-resizable-panels": "^3.0.6",
"sharp": "^0.34.4",
"tailwindcss": "^4.1.16",
"zustand": "^5.0.8"
},
"devDependencies": {
"@biomejs/biome": "2.3.2",
Expand Down
23 changes: 0 additions & 23 deletions src/components/shared/editor/CodeEditor.tsx

This file was deleted.

13 changes: 0 additions & 13 deletions src/components/shared/sections/Section.astro

This file was deleted.

33 changes: 0 additions & 33 deletions src/content.config.ts

This file was deleted.

53 changes: 0 additions & 53 deletions src/features/content/components/NavButtons.astro

This file was deleted.

4 changes: 4 additions & 0 deletions src/features/content/enums/OutputVariant.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum OutputVariant {
Stdout = "stdout",
Stderr = "stderr",
}
4 changes: 4 additions & 0 deletions src/features/content/enums/PanelVariant.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum PanelVariant {
ContentToEditor = "content-playground",
EditorToTerminal = "editor-terminal",
}
14 changes: 14 additions & 0 deletions src/features/content/hooks/usePanelContainerBreakpoints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useMemo } from "react"

export default function usePanelContainerBreakpoints(width: number) {
const size = useMemo(() => {
if (width >= 1440) return 4
if (width >= 1024) return 5
if (width >= 768) return 8
if (width >= 640) return 10
if (width >= 480) return 14
return 18
}, [width])

return { size }
}
29 changes: 29 additions & 0 deletions src/features/content/react/ReactCodeEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import CodeMirror from "@uiw/react-codemirror"
import { useCallback } from "react"
import { useRustCompilerStore } from "~/features/content/stores/useRustCompilerStore.ts"
import { rust } from "~/helpers/config"
import { gruvbox } from "~/helpers/theme"

export default function ReactCodeEditor() {
const code = useRustCompilerStore((state) => state.code)
const setCode = useRustCompilerStore((state) => state.setCode)

const onChange = useCallback(
(val: string) => {
setCode(val)
},
[setCode],
)

return (
<CodeMirror
value={code}
extensions={[rust()]}
theme={gruvbox}
onChange={onChange}
height="100%"
className="h-full"
id="editor"
/>
)
}
31 changes: 31 additions & 0 deletions src/features/content/react/ReactCollapsiblePanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { ReactNode } from "react"

interface CollapsiblePanelProps {
icon: ReactNode
title: string
children: ReactNode
isCollapsed?: boolean
}

export default function ReactCollapsiblePanel({ icon, title, children, isCollapsed = false }: CollapsiblePanelProps) {
if (isCollapsed) {
return (
<div className="flex h-full min-h-0 flex-col items-center justify-between py-4">
<div className="flex flex-col items-center gap-3">
<div className="text-primary opacity-80">{icon}</div>
<span className="text-sm font-medium [writing-mode:vertical-rl] tracking-wider opacity-90">{title}</span>
</div>
</div>
)
}

return (
<div className="flex h-full min-h-0 flex-col">
<div className="flex items-center gap-2 p-2 border-b border-stroke-color">
{icon}
<span className="text-sm font-medium">{title}</span>
</div>
{children}
</div>
)
}
16 changes: 16 additions & 0 deletions src/features/content/react/ReactExecuteRust.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { IconPlayerPlay } from "@tabler/icons-react"
import { useRustCompilerStore } from "~/features/content/stores/useRustCompilerStore.ts"

export default function ReactExecuteRust() {
const execute = useRustCompilerStore((state) => state.execute)
return (
<button
onClick={execute}
type={"button"}
className="md:absolute md:left-1/2 md:-translate-x-1/2 ml-auto flex items-center gap-1.5 bg-neutral-500/40 px-2 py-1 rounded-md
hover:bg-neutral-500/70 text-sm cursor-pointer"
>
<IconPlayerPlay size={18} /> Ejecutar
</button>
)
}
21 changes: 21 additions & 0 deletions src/features/content/react/ReactMarkdownContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { IconLicense } from "@tabler/icons-react"
import type { ReactNode } from "react"
import { PanelVariant } from "~/features/content/enums/PanelVariant.enum.ts"
import ReactCollapsiblePanel from "~/features/content/react/ReactCollapsiblePanel.tsx"
import { usePanelStore } from "~/features/content/stores/Panel.store.ts"

interface ReactMarkdownContainerProps {
children: ReactNode
}

export default function ReactMarkdownContainer({ children }: ReactMarkdownContainerProps) {
const isCollapsed = usePanelStore((state) => state.isCollapsed(`${PanelVariant.ContentToEditor}-primary`))

return (
<ReactCollapsiblePanel isCollapsed={isCollapsed} icon={<IconLicense size={16} />} title="Contenido">
<article className="scroll-container m-2 overflow-y-auto p-2">
<article className="mb-6 text-secondary min-w-[400px]">{children}</article>
</article>
</ReactCollapsiblePanel>
)
}
81 changes: 81 additions & 0 deletions src/features/content/react/ReactPanelContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { IconGripVertical } from "@tabler/icons-react"
import { type ReactNode, useEffect, useMemo, useRef } from "react"
import { type ImperativePanelHandle, Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"
import { PanelVariant } from "~/features/content/enums/PanelVariant.enum.ts"
import usePanelContainerBreakpoints from "~/features/content/hooks/usePanelContainerBreakpoints.ts"
import { usePanelStore } from "~/features/content/stores/Panel.store.ts"
import useWindowSize from "~/features/shared/hooks/useWindowSize.ts"

interface PanelContainerProps {
direction: "horizontal" | "vertical"
defaultLayout: [number, number]
first?: ReactNode
second?: ReactNode
variant: PanelVariant
}

export default function ReactPanelContainer({
first,
second,
direction = "horizontal",
defaultLayout = [50, 50],
variant,
}: PanelContainerProps) {
const { width } = useWindowSize()
const { size } = usePanelContainerBreakpoints(width)
const offset = useMemo(() => 4, [])

const registerPanel = usePanelStore((state) => state.registerPanel)
const unregisterPanel = usePanelStore((state) => state.unregisterPanel)
const setCollapsed = usePanelStore((state) => state.setCollapsed)

const primaryId = `${variant}-primary`
const secondaryId = `${variant}-secondary`

const primaryPanelRef = useRef<ImperativePanelHandle>(null)
const secondaryPanelRef = useRef<ImperativePanelHandle>(null)

useEffect(() => {
if (primaryPanelRef.current) registerPanel(primaryId, primaryPanelRef.current)
if (secondaryPanelRef.current) registerPanel(secondaryId, secondaryPanelRef.current)

return () => {
unregisterPanel(primaryId)
unregisterPanel(secondaryId)
}
}, [registerPanel, unregisterPanel, primaryId, secondaryId])

return (
<PanelGroup direction={direction} className="h-full min-h-0 grow">
<Panel
ref={primaryPanelRef}
defaultSize={defaultLayout[0]}
className="min-h-0"
minSize={size + offset}
collapsible
collapsedSize={size}
onCollapse={() => setCollapsed(primaryId, true)}
onExpand={() => setCollapsed(primaryId, false)}
>
{first}
</Panel>
<PanelResizeHandle className={"flex justify-center items-center"}>
<div className={"bg-primary mx-auto cursor-col-resize grow flex items-center justify-center"}>
<IconGripVertical size={14} className={direction === "vertical" ? "rotate-90" : ""} />
</div>
</PanelResizeHandle>
<Panel
ref={secondaryPanelRef}
defaultSize={defaultLayout[1]}
className="min-h-0"
minSize={size + offset}
collapsible
collapsedSize={size}
onCollapse={() => setCollapsed(secondaryId, true)}
onExpand={() => setCollapsed(secondaryId, false)}
>
{second}
</Panel>
</PanelGroup>
)
}
15 changes: 15 additions & 0 deletions src/features/content/react/ReactPanelHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { ReactNode } from "react"

interface ReactPanelHeaderProps {
icon: ReactNode
title: string
}

export default function ReactPanelHeader({ icon, title }: ReactPanelHeaderProps) {
return (
<div className="flex items-center gap-2 px-4 h-10 bg-light-bg border-b border-stroke-color">
{icon}
<span className="font-medium">{title}</span>
</div>
)
}
Loading
Loading