Skip to content

Commit a30a459

Browse files
committed
Merge main into page-mode-demo-no-s3
Resolved conflicts: - next.config.mjs: Kept webpack config for raw-loader support - package.json: Combined prebuild/predev scripts with --webpack flags
2 parents 78cc7f2 + 57c059c commit a30a459

File tree

47 files changed

+1959
-624
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1959
-624
lines changed

apps/master-sample-app/components/sidebar.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const sampleIdToItemName = (sampleId: string): string => {
2828
'react-comments-text-editors-lexical-lexical-comments-demo': 'lexical-comments-demo',
2929
'react-comments-dashboard-custom-dashboard-demo': 'dashboard-demo',
3030
'react-comments-dashboard-inline-comments-dashboard-inline-comments-demo': 'dashboard-inline-comments-demo',
31+
'react-comments-website-builder-freestyle-comments-freestyle-comments-demo': 'freestyle-comments-demo',
3132
'react-self-hosting-dashboard-mongo-db-dashboard-mongo-db-demo': 'dashboard-mongo-db-demo',
3233
'react-self-hosting-dashboard-postgres-dashboard-postgres-demo': 'dashboard-postgres-demo',
3334
'react-crdt-text-editors-tiptap-tiptap-crdt-demo': 'tiptap-crdt-demo',
@@ -49,6 +50,8 @@ export function Sidebar({ isOpen, onToggle, currentSampleId, onSampleSelect }: S
4950
slatejs: false,
5051
lexical: false,
5152
commentsDashboard: false,
53+
commentsWebsiteBuilder: false,
54+
commentsFreestyleComments: false,
5255
selfHosting: false,
5356
selfHostingDashboard: false,
5457
selfHostingMongoDB: false,
@@ -428,6 +431,43 @@ export function Sidebar({ isOpen, onToggle, currentSampleId, onSampleSelect }: S
428431
</button>
429432
</div>
430433
)}
434+
435+
{/* website-builder Section */}
436+
<button
437+
onClick={() => toggleSection("commentsWebsiteBuilder")}
438+
className="flex w-full items-center justify-between rounded-xl px-3 py-2.5 text-sm font-mono text-sidebar-foreground bg-sidebar-accent/50"
439+
>
440+
<span>website-builder</span>
441+
<ChevronRight className={cn("h-4 w-4 transition-transform", expandedSections.commentsWebsiteBuilder && "rotate-90")} />
442+
</button>
443+
{expandedSections.commentsWebsiteBuilder && (
444+
<div className="mt-2 ml-2 space-y-1">
445+
{/* freestyle-comments Section */}
446+
<button
447+
onClick={() => toggleSection("commentsFreestyleComments")}
448+
className="flex w-full items-center justify-between rounded-xl px-3 py-2.5 text-sm font-mono text-sidebar-foreground bg-sidebar-accent/30"
449+
>
450+
<span>freestyle-comments</span>
451+
<ChevronRight className={cn("h-4 w-4 transition-transform", expandedSections.commentsFreestyleComments && "rotate-90")} />
452+
</button>
453+
{expandedSections.commentsFreestyleComments && (
454+
<div className="mt-2 ml-2 space-y-1">
455+
<button
456+
onClick={() => {
457+
setSelectedItem("freestyle-comments-demo")
458+
onSampleSelect?.("react-comments-website-builder-freestyle-comments-freestyle-comments-demo")
459+
}}
460+
className={cn(
461+
"w-full rounded-lg px-3 py-2.5 text-left text-sm font-mono text-sidebar-foreground transition-colors",
462+
selectedItem === "freestyle-comments-demo" ? "bg-secondary" : "hover:bg-secondary/50",
463+
)}
464+
>
465+
freestyle-comments-demo
466+
</button>
467+
</div>
468+
)}
469+
</div>
470+
)}
431471
</div>
432472
)}
433473
</div>

apps/master-sample-app/components/viewer/code-display.tsx

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,20 @@ import { SampleCodeFile } from "@/types/sample"
55
import { ChevronRight, File, Folder } from "lucide-react"
66
import { cn } from "@/lib/utils"
77

8-
// Syntax highlighting function
8+
// Syntax highlighting function using markers to prevent regex from matching inside HTML tags
99
function highlightCode(code: string): string {
10+
// Use unique markers that won't appear in code
11+
const MARKERS = {
12+
COMMENT: '[[C:',
13+
STRING: '[[S:',
14+
KEYWORD: '[[K:',
15+
NUMBER: '[[N:',
16+
LITERAL: '[[L:',
17+
FUNCTION: '[[F:',
18+
TYPE: '[[T:',
19+
END: ':]]'
20+
}
21+
1022
let highlighted = code
1123

1224
// Escape HTML first
@@ -18,45 +30,91 @@ function highlightCode(code: string): string {
1830
// Comments (must be done before other highlighting)
1931
highlighted = highlighted.replace(
2032
/(\/\/.*$|\/\*[\s\S]*?\*\/)/gm,
21-
'<span class="code-comment">$1</span>'
33+
`${MARKERS.COMMENT}$1${MARKERS.END}`
2234
)
2335

24-
// Strings
36+
// Strings - but not inside already-marked regions
2537
highlighted = highlighted.replace(
2638
/("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`)/g,
27-
'<span class="code-string">$1</span>'
39+
(match) => {
40+
// Skip if already inside a marker
41+
if (match.includes('[[') || match.includes(':]]')) return match
42+
return `${MARKERS.STRING}${match}${MARKERS.END}`
43+
}
2844
)
2945

30-
// Keywords
46+
// Keywords - but not inside already-marked regions
3147
highlighted = highlighted.replace(
3248
/\b(import|export|from|const|let|var|function|return|if|else|for|while|class|interface|type|extends|implements|async|await|try|catch|throw|new|this|super|static|public|private|protected|default|case|switch|break|continue|do|in|of|typeof|instanceof|void|null|undefined|as)\b/g,
33-
'<span class="code-keyword">$1</span>'
49+
(match, p1, offset, string) => {
50+
// Check if this match is inside a marker (look for unclosed [[ before this position)
51+
const before = string.substring(0, offset)
52+
const openMarkers = (before.match(/\[\[/g) || []).length
53+
const closeMarkers = (before.match(/:]\]/g) || []).length
54+
if (openMarkers > closeMarkers) return match
55+
return `${MARKERS.KEYWORD}${match}${MARKERS.END}`
56+
}
3457
)
3558

36-
// Numbers
59+
// Numbers - but not inside already-marked regions
3760
highlighted = highlighted.replace(
3861
/\b(\d+\.?\d*)\b/g,
39-
'<span class="code-number">$1</span>'
62+
(match, p1, offset, string) => {
63+
const before = string.substring(0, offset)
64+
const openMarkers = (before.match(/\[\[/g) || []).length
65+
const closeMarkers = (before.match(/:]\]/g) || []).length
66+
if (openMarkers > closeMarkers) return match
67+
return `${MARKERS.NUMBER}${match}${MARKERS.END}`
68+
}
4069
)
4170

4271
// Boolean and special values
4372
highlighted = highlighted.replace(
4473
/\b(true|false)\b/g,
45-
'<span class="code-literal">$1</span>'
74+
(match, p1, offset, string) => {
75+
const before = string.substring(0, offset)
76+
const openMarkers = (before.match(/\[\[/g) || []).length
77+
const closeMarkers = (before.match(/:]\]/g) || []).length
78+
if (openMarkers > closeMarkers) return match
79+
return `${MARKERS.LITERAL}${match}${MARKERS.END}`
80+
}
4681
)
4782

4883
// Function names (before parenthesis)
4984
highlighted = highlighted.replace(
5085
/\b([a-zA-Z_$][a-zA-Z0-9_$]*)\s*(?=\()/g,
51-
'<span class="code-function">$1</span>'
86+
(match, p1, offset, string) => {
87+
const before = string.substring(0, offset)
88+
const openMarkers = (before.match(/\[\[/g) || []).length
89+
const closeMarkers = (before.match(/:]\]/g) || []).length
90+
if (openMarkers > closeMarkers) return match
91+
return `${MARKERS.FUNCTION}${p1}${MARKERS.END}`
92+
}
5293
)
5394

5495
// Types/Classes (PascalCase)
5596
highlighted = highlighted.replace(
5697
/\b([A-Z][a-zA-Z0-9_]*)\b/g,
57-
'<span class="code-type">$1</span>'
98+
(match, p1, offset, string) => {
99+
const before = string.substring(0, offset)
100+
const openMarkers = (before.match(/\[\[/g) || []).length
101+
const closeMarkers = (before.match(/:]\]/g) || []).length
102+
if (openMarkers > closeMarkers) return match
103+
return `${MARKERS.TYPE}${match}${MARKERS.END}`
104+
}
58105
)
59106

107+
// Convert markers to HTML spans
108+
highlighted = highlighted
109+
.replace(/\[\[C:/g, '<span class="code-comment">')
110+
.replace(/\[\[S:/g, '<span class="code-string">')
111+
.replace(/\[\[K:/g, '<span class="code-keyword">')
112+
.replace(/\[\[N:/g, '<span class="code-number">')
113+
.replace(/\[\[L:/g, '<span class="code-literal">')
114+
.replace(/\[\[F:/g, '<span class="code-function">')
115+
.replace(/\[\[T:/g, '<span class="code-type">')
116+
.replace(/:]\]/g, '</span>')
117+
60118
return highlighted
61119
}
62120

0 commit comments

Comments
 (0)