Skip to content

Commit 60835ab

Browse files
authored
Merge branch 'main' into main
2 parents 0259cd6 + 8a76a5b commit 60835ab

19 files changed

Lines changed: 1740 additions & 264 deletions

convex/users.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ export const listUsers = query({
5454
nameFilter: v.optional(v.string()),
5555
capabilityFilter: v.optional(
5656
v.array(
57-
v.union(v.literal('admin'), v.literal('disableAds'), v.literal('builder'))
57+
v.union(
58+
v.literal('admin'),
59+
v.literal('disableAds'),
60+
v.literal('builder')
61+
)
5862
)
5963
),
6064
noCapabilitiesFilter: v.optional(v.boolean()),
@@ -96,10 +100,7 @@ export const listUsers = query({
96100

97101
// No capabilities filter
98102
if (args.noCapabilitiesFilter === true) {
99-
if (
100-
!Array.isArray(user.capabilities) ||
101-
user.capabilities.length > 0
102-
) {
103+
if (!Array.isArray(user.capabilities) || user.capabilities.length > 0) {
103104
return false
104105
}
105106
}
@@ -116,7 +117,11 @@ export const listUsers = query({
116117
if (Boolean(user.adsDisabled) !== args.adsDisabledFilter) return false
117118
}
118119
if (typeof args.interestedInHidingAdsFilter === 'boolean') {
119-
if (Boolean(user.interestedInHidingAds) !== args.interestedInHidingAdsFilter) return false
120+
if (
121+
Boolean(user.interestedInHidingAds) !==
122+
args.interestedInHidingAdsFilter
123+
)
124+
return false
120125
}
121126
return true
122127
})

package.json

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@
4141
"@tailwindcss/vite": "^4.1.11",
4242
"@tanstack/react-pacer": "^0.16.3",
4343
"@tanstack/react-query": "^5.90.2",
44-
"@tanstack/react-router": "1.136.4",
45-
"@tanstack/react-router-devtools": "1.136.4",
46-
"@tanstack/react-router-ssr-query": "1.136.4",
47-
"@tanstack/react-start": "1.136.4",
44+
"@tanstack/react-router": "1.139.12",
45+
"@tanstack/react-router-devtools": "1.139.12",
46+
"@tanstack/react-router-ssr-query": "1.139.12",
47+
"@tanstack/react-start": "1.139.12",
4848
"@tanstack/react-table": "^8.21.3",
4949
"@types/d3": "^7.4.3",
5050
"@typescript-eslint/parser": "^7.2.0",
@@ -62,12 +62,11 @@
6262
"downshift": "^9.0.9",
6363
"eslint-config-react-app": "^7.0.1",
6464
"gray-matter": "^4.0.3",
65+
"hast-util-is-element": "^3.0.0",
66+
"hast-util-to-string": "^3.0.1",
6567
"html-react-parser": "^5.1.10",
6668
"import-meta-resolve": "^4.0.0",
6769
"lru-cache": "^7.13.1",
68-
"marked": "^13.0.2",
69-
"marked-alert": "^2.0.1",
70-
"marked-gfm-heading-id": "^4.0.0",
7170
"mermaid": "^11.11.0",
7271
"qss": "^3.0.0",
7372
"react": "^19.2.0",
@@ -76,11 +75,22 @@
7675
"react-icons": "^5.3.0",
7776
"react-instantsearch": "7",
7877
"react-markdown": "^6.0.3",
78+
"rehype-autolink-headings": "^7.1.0",
79+
"rehype-callouts": "^2.1.2",
80+
"rehype-parse": "^9.0.1",
81+
"rehype-raw": "^7.0.0",
82+
"rehype-slug": "^6.0.0",
83+
"rehype-stringify": "^10.0.1",
84+
"remark-gfm": "^4.0.1",
85+
"remark-parse": "^11.0.0",
86+
"remark-rehype": "^11.1.2",
7987
"remix-utils": "^8.5.0",
8088
"remove-markdown": "^0.5.0",
8189
"shiki": "^1.4.0",
8290
"tailwind-merge": "^1.14.0",
8391
"tiny-invariant": "^1.3.3",
92+
"unified": "^11.0.5",
93+
"unist-util-visit": "^5.0.0",
8494
"vite-bundle-analyzer": "^1.2.1",
8595
"vite-tsconfig-paths": "^5.0.1",
8696
"zod": "^4.0.17",

pnpm-lock.yaml

Lines changed: 1096 additions & 199 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/Doc.tsx

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import { marked } from 'marked'
2-
import markedAlert from 'marked-alert'
3-
import { getHeadingList, gfmHeadingId } from 'marked-gfm-heading-id'
41
import * as React from 'react'
52
import {
63
BsArrowsCollapseVertical,
@@ -11,6 +8,10 @@ import { twMerge } from 'tailwind-merge'
118
import { useWidthToggle } from '~/components/DocsLayout'
129
import { DocTitle } from '~/components/DocTitle'
1310
import { Markdown } from '~/components/Markdown'
11+
import {
12+
MarkdownHeadingProvider,
13+
useMarkdownHeadings,
14+
} from '~/components/MarkdownHeadingContext'
1415
import { AdGate } from '~/contexts/AdsContext'
1516
import { CopyMarkdownButton } from './CopyMarkdownButton'
1617
import { GamHeader, GamLeader } from './Gam'
@@ -28,7 +29,7 @@ type DocProps = {
2829
colorTo?: string
2930
}
3031

31-
export function Doc({
32+
function DocContent({
3233
title,
3334
content,
3435
repo,
@@ -38,17 +39,7 @@ export function Doc({
3839
colorFrom,
3940
colorTo,
4041
}: DocProps) {
41-
const { markup, headings } = React.useMemo(() => {
42-
const markup = marked.use(
43-
{ gfm: true },
44-
gfmHeadingId(),
45-
markedAlert()
46-
)(content) as string
47-
48-
const headings = getHeadingList()
49-
50-
return { markup, headings }
51-
}, [content])
42+
const { headings } = useMarkdownHeadings()
5243

5344
const isTocVisible = shouldRenderToc && headings && headings.length > 1
5445

@@ -107,7 +98,7 @@ export function Doc({
10798
headingElements.forEach((el) => observer.observe(el))
10899

109100
return () => observer.disconnect()
110-
}, [])
101+
}, [headings])
111102

112103
return (
113104
<div className="flex-1 min-h-0 flex flex-col">
@@ -168,7 +159,7 @@ export function Doc({
168159
'styled-markdown-content'
169160
)}
170161
>
171-
<Markdown htmlMarkup={markup} />
162+
<Markdown rawContent={content} />
172163
</div>
173164
<div className="h-12" />
174165
<div className="w-full h-px bg-gray-500 opacity-30" />
@@ -197,3 +188,11 @@ export function Doc({
197188
</div>
198189
)
199190
}
191+
192+
export function Doc(props: DocProps) {
193+
return (
194+
<MarkdownHeadingProvider>
195+
<DocContent {...props} />
196+
</MarkdownHeadingProvider>
197+
)
198+
}

src/components/MaintainerCard.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,11 @@ export function MaintainerRowCard({
419419
)
420420
}
421421

422-
export function MaintainerCard({ maintainer, libraryId, hideLibraries }: MaintainerCardProps) {
422+
export function MaintainerCard({
423+
maintainer,
424+
libraryId,
425+
hideLibraries,
426+
}: MaintainerCardProps) {
423427
const libraries = getPersonsMaintainerOf(maintainer)
424428
const [showAllLibraries, setShowAllLibraries] = useState(false)
425429

src/components/Markdown.tsx

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import parse, {
1010
Element,
1111
HTMLReactParserOptions,
1212
} from 'html-react-parser'
13-
import { marked } from 'marked'
14-
import { gfmHeadingId } from 'marked-gfm-heading-id'
15-
import markedAlert from 'marked-alert'
1613
import mermaid from 'mermaid'
1714
import { useToast } from '~/components/ToastProvider'
1815
import { twMerge } from 'tailwind-merge'
16+
import { useMarkdownHeadings } from '~/components/MarkdownHeadingContext'
17+
import { renderMarkdown } from '~/utils/markdown'
18+
import { Tabs } from '~/components/Tabs'
1919

2020
const CustomHeading = ({
2121
Comp,
@@ -194,7 +194,7 @@ export function CodeBlock({
194194
return (
195195
<div
196196
className={twMerge(
197-
'w-full max-w-full relative not-prose border border-gray-500/20 rounded-md [&_pre]:rounded-md',
197+
'codeblock w-full max-w-full relative not-prose border border-gray-500/20 rounded-md [&_pre]:rounded-md [*[data-tab]_&]:only:border-0',
198198
props.className
199199
)}
200200
style={props.style}
@@ -288,6 +288,35 @@ const getHighlighter = cache(async (language: string, themes: string[]) => {
288288
const options: HTMLReactParserOptions = {
289289
replace: (domNode) => {
290290
if (domNode instanceof Element && domNode.attribs) {
291+
if (domNode.name === 'md-comment-component') {
292+
const componentName = domNode.attribs['data-component']
293+
const rawAttributes = domNode.attribs['data-attributes']
294+
const attributes: Record<string, any> = {}
295+
try {
296+
Object.assign(attributes, JSON.parse(rawAttributes))
297+
} catch {
298+
// ignore JSON parse errors and fall back to empty props
299+
}
300+
301+
switch (componentName?.toLowerCase()) {
302+
case 'tabs': {
303+
const tabs = attributes.tabs
304+
const panelElements = domNode.children?.filter(
305+
(child): child is Element =>
306+
child instanceof Element && child.name === 'md-tab-panel'
307+
)
308+
309+
const children = panelElements?.map((panel) =>
310+
domToReact(panel.children as any, options)
311+
)
312+
313+
return <Tabs tabs={tabs} children={children as any} />
314+
}
315+
default:
316+
return <div>{domToReact(domNode.children as any, options)}</div>
317+
}
318+
}
319+
291320
const replacer = markdownComponents[domNode.name]
292321
if (replacer) {
293322
return React.createElement(
@@ -302,24 +331,35 @@ const options: HTMLReactParserOptions = {
302331
},
303332
}
304333

305-
type MarkdownProps = { rawContent?: string; htmlMarkup?: string }
334+
type MarkdownProps = {
335+
rawContent?: string
336+
htmlMarkup?: string
337+
}
306338

307339
export function Markdown({ rawContent, htmlMarkup }: MarkdownProps) {
308-
return React.useMemo(() => {
309-
if (rawContent) {
310-
const markup = marked.use(
311-
{ gfm: true },
312-
gfmHeadingId(),
313-
markedAlert()
314-
)(rawContent) as string
340+
const { setHeadings } = useMarkdownHeadings()
315341

316-
return parse(markup, options)
342+
const rendered = React.useMemo(() => {
343+
if (rawContent) {
344+
return renderMarkdown(rawContent)
317345
}
318346

319347
if (htmlMarkup) {
320-
return parse(htmlMarkup, options)
348+
return { markup: htmlMarkup, headings: [] }
321349
}
322350

323-
return null
351+
return { markup: '', headings: [] }
324352
}, [rawContent, htmlMarkup])
353+
354+
React.useEffect(() => {
355+
setHeadings(rendered.headings)
356+
}, [rendered.headings, setHeadings])
357+
358+
return React.useMemo(() => {
359+
if (!rendered.markup) {
360+
return null
361+
}
362+
363+
return parse(rendered.markup, options)
364+
}, [rendered.markup])
325365
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import * as React from 'react'
2+
import { MarkdownHeading } from '~/utils/markdown/processor'
3+
4+
const MarkdownHeadingContext = React.createContext<{
5+
headings: MarkdownHeading[]
6+
setHeadings(headings: MarkdownHeading[]): void
7+
}>({
8+
headings: [],
9+
setHeadings: () => undefined,
10+
})
11+
12+
export function MarkdownHeadingProvider({
13+
children,
14+
}: {
15+
children: React.ReactNode
16+
}) {
17+
const [headings, setHeadings] = React.useState<MarkdownHeading[]>([])
18+
19+
const value = React.useMemo(() => ({ headings, setHeadings }), [headings])
20+
21+
return (
22+
<MarkdownHeadingContext.Provider value={value}>
23+
{children}
24+
</MarkdownHeadingContext.Provider>
25+
)
26+
}
27+
28+
export function useMarkdownHeadings() {
29+
return React.useContext(MarkdownHeadingContext)
30+
}

0 commit comments

Comments
 (0)