@clidey/dory 0.29.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/bin/dist/dory.js +115 -29
  2. package/bin/dist/dory.js.map +1 -1
  3. package/package.json +12 -4
  4. package/.dockerignore +0 -4
  5. package/CLAUDE.md +0 -178
  6. package/CODE_OF_CONDUCT.md +0 -128
  7. package/CONTRIBUTING.md +0 -91
  8. package/SECURITY.md +0 -11
  9. package/bin/dory.ts +0 -433
  10. package/dist/favicon.svg +0 -75
  11. package/dist/frontmatter.json +0 -77
  12. package/dist/index.html +0 -55
  13. package/dist/llms.txt +0 -561
  14. package/dist/logo/logo.svg +0 -18
  15. package/docs/api-playground-demo.mdx +0 -119
  16. package/docs/api-reference/asyncapi.json +0 -324
  17. package/docs/api-reference/openapi.json +0 -366
  18. package/docs/api-reference/operations/create.mdx +0 -5
  19. package/docs/api-reference/operations/delete.mdx +0 -5
  20. package/docs/api-reference/operations/get.mdx +0 -5
  21. package/docs/api-reference/operations/update.mdx +0 -5
  22. package/docs/api-reference/websocket-operations/receive-chat-message.mdx +0 -5
  23. package/docs/api-reference/websocket-operations/receive-notifications.mdx +0 -5
  24. package/docs/api-reference/websocket-operations/receive-presence-update.mdx +0 -5
  25. package/docs/api-reference/websocket-operations/send-chat-message.mdx +0 -5
  26. package/docs/api-reference/websocket-operations/send-presence-update.mdx +0 -5
  27. package/docs/dory.json +0 -64
  28. package/docs/favicon.svg +0 -75
  29. package/docs/features.mdx +0 -440
  30. package/docs/introduction.mdx +0 -44
  31. package/docs/logo/logo.svg +0 -18
  32. package/docs/websocket-playground-demo.mdx +0 -135
  33. package/index.html +0 -54
  34. package/scripts/generate-frontmatter-json.js +0 -154
  35. package/scripts/generate-llm-txt.js +0 -115
  36. package/src/app.css +0 -5
  37. package/src/app.tsx +0 -13
  38. package/src/components/dropdown.tsx +0 -53
  39. package/src/components/hooks.tsx +0 -28
  40. package/src/components/loading.tsx +0 -21
  41. package/src/components/mdx-provider.tsx +0 -13
  42. package/src/components/navigation.tsx +0 -58
  43. package/src/components/notification.tsx +0 -13
  44. package/src/components/routes.tsx +0 -92
  45. package/src/components/search-index.ts +0 -43
  46. package/src/components/search.tsx +0 -435
  47. package/src/components/store.ts +0 -216
  48. package/src/config/mdx.js +0 -12
  49. package/src/config/mdx.ts +0 -12
  50. package/src/main.tsx +0 -22
  51. package/src/mdx/accordion.tsx +0 -41
  52. package/src/mdx/api-playground.tsx +0 -659
  53. package/src/mdx/api.tsx +0 -354
  54. package/src/mdx/async-api.tsx +0 -353
  55. package/src/mdx/callout.tsx +0 -64
  56. package/src/mdx/card.tsx +0 -54
  57. package/src/mdx/code.tsx +0 -289
  58. package/src/mdx/expandable.tsx +0 -36
  59. package/src/mdx/fence.tsx +0 -74
  60. package/src/mdx/icon.tsx +0 -73
  61. package/src/mdx/latex.tsx +0 -26
  62. package/src/mdx/list.tsx +0 -7
  63. package/src/mdx/mdx.tsx +0 -47
  64. package/src/mdx/mermaid.tsx +0 -147
  65. package/src/mdx/open-api.tsx +0 -311
  66. package/src/mdx/processor.ts +0 -174
  67. package/src/mdx/source.tsx +0 -58
  68. package/src/mdx/step.tsx +0 -51
  69. package/src/mdx/table.tsx +0 -20
  70. package/src/mdx/tag.tsx +0 -53
  71. package/src/mdx/text.tsx +0 -99
  72. package/src/mdx/websocket-playground.tsx +0 -824
  73. package/src/plugins/docs-assets.ts +0 -79
  74. package/src/plugins/frontmatter-dev-server.ts +0 -158
  75. package/src/plugins/frontmatter-generator.ts +0 -157
  76. package/src/plugins/html-metadata-injector.ts +0 -76
  77. package/src/plugins/llm-txt-dev-server.ts +0 -183
  78. package/src/plugins/llm-txt-generator.ts +0 -186
  79. package/src/plugins/sanitize.ts +0 -163
  80. package/src/plugins/unified-mdx-plugin.ts +0 -35
  81. package/src/theme.scss +0 -72
  82. package/src/types/config.ts +0 -47
  83. package/src/ui/header.tsx +0 -91
  84. package/src/ui/layout.tsx +0 -226
  85. package/src/ui/mobile-navigation.tsx +0 -64
  86. package/src/ui/prev-next-link.tsx +0 -74
  87. package/src/ui/table-of-content.tsx +0 -166
  88. package/src/utils/colors.ts +0 -54
  89. package/src/utils/fonts.ts +0 -23
  90. package/src/utils/functions.ts +0 -12
  91. package/src/vite-env.d.ts +0 -1
  92. package/tsconfig.app.json +0 -33
  93. package/tsconfig.bin.json +0 -24
  94. package/tsconfig.json +0 -7
  95. package/tsconfig.node.json +0 -26
  96. package/vite.config.ts +0 -43
@@ -1,64 +0,0 @@
1
- import { Alert, AlertTitle, AlertDescription } from '@clidey/ux'
2
- import { Icon } from "./icon"
3
-
4
- const typeToVariant = {
5
- note: 'default',
6
- warning: 'destructive',
7
- info: 'default',
8
- tip: 'default',
9
- check: 'default',
10
- } as const
11
-
12
- const icons = {
13
- note: 'InfoCircle',
14
- warning: 'AlertTriangle',
15
- info: 'InfoCircle',
16
- tip: 'Lightbulb',
17
- check: 'CheckCircle',
18
- } as const
19
-
20
- const typeColors = {
21
- note: 'border-emerald-500/30 bg-emerald-500/10 text-emerald-900 dark:text-emerald-200',
22
- warning: 'border-amber-500/30 bg-amber-500/10 text-amber-900 dark:text-amber-200 *:data-[slot=alert-description]:text-inherit dark:data-[slot=alert-description]:text-inherit',
23
- info: 'border-blue-500/30 bg-blue-500/10 text-blue-900 dark:text-blue-200',
24
- tip: 'border-green-500/30 bg-green-500/10 text-green-900 dark:text-green-200',
25
- check: 'border-purple-500/30 bg-purple-500/10 text-purple-900 dark:text-purple-200',
26
- }
27
-
28
- export function Callout({
29
- title,
30
- children,
31
- type = 'note',
32
- }: {
33
- title: string
34
- children: React.ReactNode
35
- type?: keyof typeof icons
36
- }) {
37
- return (
38
- <Alert variant={typeToVariant[type]} className={`my-6 ${typeColors[type]}`}>
39
- <Icon icon={icons[type]} className="h-4 w-4" />
40
- <AlertTitle>{title}</AlertTitle>
41
- <AlertDescription>{children}</AlertDescription>
42
- </Alert>
43
- )
44
- }
45
-
46
- export function Note({ children }: { children: React.ReactNode }) {
47
- return <Callout type="note" title="Note">{children}</Callout>
48
- }
49
-
50
- export function Warning({ children }: { children: React.ReactNode }) {
51
- return <Callout type="warning" title="Warning">{children}</Callout>
52
- }
53
-
54
- export function Info({ children }: { children: React.ReactNode }) {
55
- return <Callout type="info" title="Info">{children}</Callout>
56
- }
57
-
58
- export function Tip({ children }: { children: React.ReactNode }) {
59
- return <Callout type="tip" title="Tip">{children}</Callout>
60
- }
61
-
62
- export function Check({ children }: { children: React.ReactNode }) {
63
- return <Callout type="check" title="Check">{children}</Callout>
64
- }
package/src/mdx/card.tsx DELETED
@@ -1,54 +0,0 @@
1
- import classNames from "classnames";
2
- import {
3
- Card as UXCard,
4
- CardHeader,
5
- CardTitle,
6
- CardDescription,
7
- CardContent
8
- } from '@clidey/ux'
9
- import { Icon } from "./icon";
10
- import type { ComponentChildren } from "preact";
11
-
12
- export function CardGroup({ children, cols = 2 }: { children: React.ReactNode; cols?: number }) {
13
- return (
14
- <div className={classNames(
15
- 'not-prose my-12 grid grid-cols-1 gap-6',
16
- cols === 2 && 'sm:grid-cols-2',
17
- cols === 3 && 'sm:grid-cols-3',
18
- cols === 4 && 'sm:grid-cols-4'
19
- )}>
20
- {children}
21
- </div>
22
- )
23
- }
24
-
25
- export function Card({
26
- title,
27
- description,
28
- href,
29
- icon,
30
- children,
31
- }: {
32
- title?: string
33
- description?: string
34
- href?: string
35
- icon?: string
36
- children?: ComponentChildren
37
- }) {
38
- return (
39
- <UXCard className="group relative border-ring border-1 border-black/10 dark:border-white/10">
40
- {href && <a href={href} className="absolute inset-0 z-10" aria-label={title} />}
41
- <CardHeader>
42
- <div className="flex items-center gap-3">
43
- {icon && <Icon icon={icon} className="h-8 w-8" />}
44
- <CardTitle className="text-base">{title}</CardTitle>
45
- </div>
46
- </CardHeader>
47
- <CardContent>
48
- <CardDescription className="text-sm leading-tight">
49
- {description ?? children}
50
- </CardDescription>
51
- </CardContent>
52
- </UXCard>
53
- )
54
- }
package/src/mdx/code.tsx DELETED
@@ -1,289 +0,0 @@
1
- import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
2
- import { ClipboardIcon } from '@heroicons/react/24/outline'
3
- import classNames from 'classnames'
4
- import {
5
- Children,
6
- createContext,
7
- isValidElement,
8
- useEffect,
9
- useState
10
- } from 'react'
11
- import { Tag } from './tag'
12
- import { toTitleCase } from '../utils/functions'
13
- import { Button, Card } from '@clidey/ux'
14
- import { CheckIcon } from 'lucide-react'
15
-
16
- export const supportedLanguages = {
17
- 'python': 'Python',
18
- 'py': 'Python',
19
- 'javascript': 'JavaScript',
20
- 'js': 'JavaScript',
21
- 'typescript': 'TypeScript',
22
- 'ts': 'TypeScript',
23
- 'java': 'Java',
24
- 'c': 'C',
25
- 'cpp': 'C++',
26
- 'csharp': 'C#',
27
- 'cs': 'C#',
28
- 'rust': 'Rust',
29
- 'go': 'Go',
30
- 'ruby': 'Ruby',
31
- 'php': 'PHP',
32
- 'swift': 'Swift',
33
- 'kotlin': 'Kotlin',
34
- 'scala': 'Scala',
35
- 'haskell': 'Haskell',
36
- 'erlang': 'Erlang',
37
- 'elixir': 'Elixir',
38
- 'markdown': 'Markdown',
39
- 'md': 'Markdown',
40
- 'html': 'HTML',
41
- 'css': 'CSS',
42
- 'json': 'JSON',
43
- 'yaml': 'YAML',
44
- 'yml': 'YAML',
45
- 'toml': 'TOML',
46
- 'bash': 'Bash',
47
- 'markup': 'Markup',
48
- 'xml': 'XML',
49
- 'jsx': 'JSX',
50
- 'tsx': 'TSX',
51
- 'objectivec': 'Objective-C',
52
- 'js-extras': 'JavaScript Extras',
53
- 'reason': 'Reason',
54
- 'graphql': 'GraphQL',
55
- }
56
-
57
- function getPanelTitle(props: { className?: string }) {
58
- const { className } = props
59
- if (className) {
60
- const language = className.replace('language-', '') as keyof typeof supportedLanguages;
61
- return supportedLanguages[language] || toTitleCase(language)
62
- }
63
- return 'Code'
64
- }
65
-
66
- function CopyButton({ code }: { code: string }) {
67
- const [copyCount, setCopyCount] = useState(0)
68
- const copied = copyCount > 0
69
-
70
- useEffect(() => {
71
- if (copied) {
72
- const timeout = setTimeout(() => setCopyCount(0), 1000)
73
- return () => clearTimeout(timeout)
74
- }
75
- }, [copied])
76
-
77
- return (
78
- <Button
79
- className={classNames(
80
- 'group/button absolute top-1 right-2 overflow-hidden rounded-full py-1 pr-3 pl-2 text-2xs font-medium opacity-0 backdrop-blur-sm transition group-hover:opacity-100 focus:opacity-100',
81
- {
82
- 'bg-emerald-400/10 ring-1 ring-emerald-400/20 ring-inset': copied,
83
- 'bg-white/5 hover:bg-white/7.5 dark:bg-white/2.5 dark:hover:bg-white/5': !copied,
84
- }
85
- )}
86
- onClick={() => {
87
- window.navigator.clipboard.writeText(code).then(() => {
88
- setCopyCount((count) => count + 1)
89
- })
90
- }}
91
- >
92
- <span
93
- aria-hidden={copied}
94
- className={classNames(
95
- 'pointer-events-none flex items-center gap-0.5 text-zinc-400 transition duration-300 text-sm',
96
- copied && '-translate-y-1.5 opacity-0',
97
- )}
98
- >
99
- <ClipboardIcon className="h-4 w-4 fill-zinc-500/20 stroke-zinc-500 transition-colors group-hover/button:stroke-zinc-400" />
100
- </span>
101
- <span
102
- aria-hidden={!copied}
103
- className={classNames(
104
- 'pointer-events-none absolute inset-0 flex items-center justify-center text-emerald-400 transition duration-300 text-sm',
105
- !copied && 'translate-y-1.5 opacity-0',
106
- )}
107
- >
108
- <CheckIcon className="h-4 w-4" />
109
- </span>
110
- </Button>
111
- )
112
- }
113
-
114
- function CodePanelHeader({ tag, label }: { tag?: string; label?: string }) {
115
- if (!tag && !label) return null
116
-
117
- return (
118
- <div className="flex h-9 items-center gap-2 border-y border-t-transparent border-b-white/7.5 bg-white/2.5 px-4 dark:border-b-white/5 dark:bg-white/1">
119
- {tag && (
120
- <div className="dark flex">
121
- <Tag variant="small">{tag}</Tag>
122
- </div>
123
- )}
124
- {tag && label && <span className="h-0.5 w-0.5 rounded-full bg-zinc-500" />}
125
- {label && <span className="font-mono text-xs text-zinc-400">{label}</span>}
126
- </div>
127
- )
128
- }
129
-
130
- function CodePanel({
131
- children,
132
- tag,
133
- label,
134
- code,
135
- }: {
136
- children: React.ReactNode
137
- tag?: string
138
- label?: string
139
- code?: string
140
- }) {
141
- const child = Children.only(children)
142
-
143
- if (isValidElement(child)) {
144
- // @ts-expect-error
145
- tag = child.props.tag ?? tag
146
- // @ts-expect-error
147
- label = child.props.label ?? label
148
- // @ts-expect-error
149
- code = child.props.code ?? code
150
- }
151
-
152
- if (!code) {
153
- // @ts-expect-error
154
- code = child.props.children
155
- }
156
-
157
- return (
158
- <div className="group dark:bg-white/2.5">
159
- <CodePanelHeader tag={tag} label={label} />
160
- <div className="relative">
161
- <pre className="overflow-x-auto p-4 text-xs">{children}</pre>
162
- <CopyButton code={code ?? ''} />
163
- </div>
164
- </div>
165
- )
166
- }
167
-
168
- function CodeGroupHeader({
169
- title,
170
- children,
171
- selectedIndex,
172
- }: {
173
- title: string
174
- children: React.ReactNode
175
- selectedIndex: number
176
- }) {
177
- const hasTabs = Children.count(children) > 1
178
-
179
- if (!title && !hasTabs) return null
180
-
181
- return (
182
- <div className="flex flex-wrap items-start gap-x-4 px-4 pb-2">
183
- {title && (
184
- <p className="mr-auto pt-3 text-xs font-semibold">
185
- {title}
186
- </p>
187
- )}
188
- {hasTabs && (
189
- <TabList className="-mb-px flex gap-4 text-xs font-medium">
190
- {Children.map(children, (child, index) => {
191
- if (!isValidElement(child)) return null
192
-
193
- const childProps = (child as preact.JSX.Element).props?.children?.props ?? {}
194
- const panelTitle = getPanelTitle(childProps)
195
-
196
- return (
197
- <Tab
198
- key={index}
199
- className={classNames(
200
- 'pt-2 transition data-selected:not-data-focus:outline-hidden',
201
- index === selectedIndex
202
- ? 'border-emerald-500 text-emerald-400'
203
- : 'border-transparent text-zinc-400 hover:text-zinc-300',
204
- )}
205
- >
206
- {panelTitle}
207
- </Tab>
208
- )
209
- })}
210
- </TabList>
211
- )}
212
- </div>
213
- )
214
- }
215
-
216
- function CodeGroupPanels({
217
- children,
218
- ...props
219
- }: React.ComponentPropsWithoutRef<typeof CodePanel>) {
220
- const hasTabs = Children.count(children) > 1
221
-
222
- if (hasTabs) {
223
- return (
224
- <TabPanels>
225
- {Children.map(children, (child, index) => (
226
- <TabPanel key={index}>
227
- <CodePanel {...props}>{child}</CodePanel>
228
- </TabPanel>
229
- ))}
230
- </TabPanels>
231
- )
232
- }
233
-
234
- return <CodePanel {...props}>{children}</CodePanel>
235
- }
236
-
237
- export const CodeGroupContext = createContext(false)
238
-
239
- export function CodeGroup({
240
- children,
241
- title,
242
- ...props
243
- }: React.ComponentPropsWithoutRef<typeof CodeGroupPanels> & { title: string }) {
244
- const [selectedIndex, setSelectedIndex] = useState(0)
245
-
246
- const childrenArray = Children.toArray(children)
247
-
248
- const hasTabs = childrenArray.length > 1
249
-
250
- const header = (
251
- <CodeGroupHeader title={title} selectedIndex={selectedIndex}>
252
- {children}
253
- </CodeGroupHeader>
254
- )
255
- const panels = <CodeGroupPanels {...props}>{children}</CodeGroupPanels>
256
-
257
- return (
258
- <CodeGroupContext.Provider value={true}>
259
- {hasTabs ? (
260
- <Card className="py-0 border-black/10 bg-none overflow-hidden mb-4">
261
- <TabGroup
262
- as="div"
263
- selectedIndex={selectedIndex}
264
- onChange={setSelectedIndex}
265
- >
266
- <div className="not-prose">
267
- {header}
268
- {panels}
269
- </div>
270
- </TabGroup>
271
- </Card>
272
- ) : (
273
- <Card className="py-0 border-black/10 bg-none overflow-hidden mb-4">
274
- <div className="not-prose">
275
- {header}
276
- {panels}
277
- </div>
278
- </Card>
279
- )}
280
- </CodeGroupContext.Provider>
281
- )
282
- }
283
-
284
- export function Code({
285
- children,
286
- ...props
287
- }: React.ComponentPropsWithoutRef<'code'>) {
288
- return <code className={classNames('dory-mdx-code rounded-md py-1 text-sm px-2', props.className)} {...props}>{children}</code>
289
- }
@@ -1,36 +0,0 @@
1
- import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from "@clidey/ux";
2
- import { Icon } from './icon';
3
-
4
- export function Expandable({
5
- title,
6
- children,
7
- icon,
8
- }: {
9
- title: string
10
- children: React.ReactNode
11
- icon?: React.ComponentProps<typeof Icon>['icon']
12
- }) {
13
- return (
14
- <Accordion
15
- type="single"
16
- collapsible
17
- className="my-6 rounded-xl border border-slate-200 dark:border-slate-700"
18
- >
19
- <AccordionItem value="expandable">
20
- <AccordionTrigger className="group flex w-full items-start justify-between text-left text-slate-900 dark:text-white p-6">
21
- <div className="flex items-center gap-2">
22
- {icon && <Icon icon={icon} className="h-8 w-8" />}
23
- <span className="text-base font-display text-slate-900 dark:text-white">{title}</span>
24
- </div>
25
- </AccordionTrigger>
26
- <AccordionContent asChild>
27
- <dd className="px-6 pb-6">
28
- <div className="text-sm text-slate-700 dark:text-slate-400 leading-tight [&>p]:mb-0">
29
- {children}
30
- </div>
31
- </dd>
32
- </AccordionContent>
33
- </AccordionItem>
34
- </Accordion>
35
- );
36
- }
package/src/mdx/fence.tsx DELETED
@@ -1,74 +0,0 @@
1
- import { Fragment, Suspense, useContext } from 'preact/compat'
2
- import { Highlight, themes } from 'prism-react-renderer'
3
- import { Code, CodeGroup, CodeGroupContext, supportedLanguages } from './code'
4
- import { MermaidRenderer } from './mermaid'
5
- import { Loading } from '../components/loading'
6
- import { useTheme } from '@clidey/ux'
7
- import classNames from 'classnames'
8
-
9
-
10
- export function Fence({
11
- children,
12
- language,
13
- }: {
14
- children: string
15
- language: string
16
- }) {
17
- const isDark = useTheme().theme === 'dark';
18
-
19
- if (language === 'mermaid') {
20
- return (
21
- <div className="mermaid-container">
22
- <Suspense fallback={<Loading />}>
23
- <MermaidRenderer content={children} />
24
- </Suspense>
25
- </div>
26
- )
27
- }
28
-
29
- const supportedLanguage = supportedLanguages[language as keyof typeof supportedLanguages] ?? language
30
-
31
- return (
32
- <Highlight
33
- code={children.trimEnd()}
34
- language={supportedLanguage}
35
- theme={isDark ? themes.vsDark : themes.vsLight}>
36
- {({ className, style, tokens, getTokenProps }) => (
37
- <pre>
38
- <Code className={classNames(className, "whitespace-pre-wrap")} style={style} title={supportedLanguage}>
39
- {tokens.map((line, lineIndex) => (
40
- <Fragment key={lineIndex}>
41
- {line
42
- .filter((token) => !token.empty)
43
- .map((token, tokenIndex) => (
44
- <span key={tokenIndex} {...getTokenProps({ token })} />
45
- ))}
46
- {'\n'}
47
- </Fragment>
48
- ))}
49
- </Code>
50
- </pre>
51
- )}
52
- </Highlight>
53
- )
54
- }
55
- export function Pre(props: { children: { props: { className?: string; children?: string } } }) {
56
- const child = props.children?.props
57
-
58
- // Safely handle className that might not be a string
59
- const className = child?.className || ''
60
- const language = supportedLanguages[className.replace('language-', '') as keyof typeof supportedLanguages] ?? className.replace('language-', '')
61
- const code = child?.children || ''
62
-
63
- // Check if we're inside a CodeGroup context
64
- const isInCodeGroup = useContext(CodeGroupContext);
65
-
66
- const fence = <Fence language={language}>{code}</Fence>
67
-
68
- // If we're not in a CodeGroup, wrap the Fence in one
69
- if (!isInCodeGroup && language !== 'mermaid') {
70
- return <CodeGroup title={language}>{fence}</CodeGroup>
71
- }
72
-
73
- return fence
74
- }
package/src/mdx/icon.tsx DELETED
@@ -1,73 +0,0 @@
1
- import { library } from '@fortawesome/fontawesome-svg-core'
2
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
3
- import * as solidIcons from '@fortawesome/free-solid-svg-icons'
4
- import * as regularIcons from '@fortawesome/free-regular-svg-icons'
5
- import * as brandIcons from '@fortawesome/free-brands-svg-icons'
6
- import classNames from 'classnames'
7
- import * as LucideIcons from 'lucide-react'
8
-
9
- // Map types to icon sets and FontAwesome prefixes
10
- const iconSets = {
11
- solid: solidIcons,
12
- regular: regularIcons,
13
- brands: brandIcons,
14
- }
15
-
16
- const prefixes = {
17
- solid: 'fas',
18
- regular: 'far',
19
- brands: 'fab',
20
- } as const
21
-
22
- export function Icon({
23
- icon,
24
- iconType = 'solid',
25
- color = '',
26
- size = 24,
27
- className,
28
- ...rest
29
- }: {
30
- icon: string
31
- iconType?: keyof typeof iconSets
32
- color?: string
33
- size?: number
34
- } & Omit<React.ComponentPropsWithoutRef<'svg'>, 'color'>) {
35
- // Convert kebab-case or snake_case to PascalCase (for Lucide and FA variable names)
36
- const pascalCase = icon
37
- .replace(/[-_](.)/g, (_, group1) => group1.toUpperCase())
38
- .replace(/^(.)/, (_, group1) => group1.toUpperCase())
39
-
40
- // --- Try Lucide First ---
41
- const LucideComponent = LucideIcons[pascalCase as keyof typeof LucideIcons] as any
42
- if (LucideComponent) {
43
- return (
44
- <LucideComponent
45
- className={classNames("stroke-black dark:stroke-white", className)}
46
- color={color}
47
- size={size}
48
- {...rest}
49
- />
50
- )
51
- }
52
-
53
- // --- Try Font Awesome ---
54
- const faSet = iconSets[iconType] ?? solidIcons
55
- const iconKey = `fa${pascalCase}` as keyof typeof faSet
56
- const faIcon = faSet[iconKey]
57
-
58
- if (faIcon && typeof faIcon === 'object' && 'iconName' in faIcon) {
59
- library.add(faIcon)
60
- return (
61
- <FontAwesomeIcon
62
- icon={[prefixes[iconType] || 'fas', faIcon.iconName] as any}
63
- className={classNames("stroke-black dark:stroke-white", className)}
64
- color={color as any}
65
- size={size as any}
66
- {...rest as any}
67
- />
68
- )
69
- }
70
-
71
- console.warn(`⚠️ Icon not found: "${icon}" (converted to ${iconKey}) in ${iconType}`)
72
- return null // or return a default/fallback icon if preferred
73
- }
package/src/mdx/latex.tsx DELETED
@@ -1,26 +0,0 @@
1
- import { useEffect, useRef } from 'react'
2
- import katex from 'katex'
3
- import 'katex/dist/katex.min.css'
4
-
5
- interface LatexProps {
6
- children: string
7
- }
8
-
9
- export function Latex({ children }: LatexProps) {
10
- const containerRef = useRef<HTMLDivElement>(null)
11
-
12
- useEffect(() => {
13
- if (containerRef.current) {
14
- try {
15
- katex.render(children, containerRef.current, {
16
- displayMode: true,
17
- throwOnError: false,
18
- })
19
- } catch (error) {
20
- console.error('Error rendering LaTeX:', error)
21
- }
22
- }
23
- }, [children])
24
-
25
- return <div ref={containerRef} className="my-4" />
26
- }
package/src/mdx/list.tsx DELETED
@@ -1,7 +0,0 @@
1
- import type { JSX } from 'preact/jsx-runtime';
2
-
3
- export const UnorderedList = (props: JSX.IntrinsicElements['ul']) => <ul className="list-disc list-inside my-2" {...props} />;
4
-
5
- export const OrderedList = (props: JSX.IntrinsicElements['ol']) => <ol className="list-decimal list-inside my-2" {...props} />;
6
-
7
- export const ListItem = (props: JSX.IntrinsicElements['li']) => <li className="ml-4 mt-2" {...props} />;
package/src/mdx/mdx.tsx DELETED
@@ -1,47 +0,0 @@
1
- import { useEffect, useRef } from 'preact/hooks';
2
- import { usePathname } from 'wouter-preact/use-browser-location';
3
- import { completeFrontMatter } from '../components/store';
4
-
5
- export { h1, h2, h3, h4, h5, h6, p, Row, Col, Anchor as a, Image as img } from './text';
6
- export { Code as code, CodeGroup } from './code';
7
- export * from './tag';
8
- export { Pre as pre } from './fence';
9
- export { Accordion, AccordionGroup } from './accordion';
10
- export { Icon } from './icon';
11
- export { Card, CardGroup } from './card';
12
- export { Callout, Note, Warning, Info, Tip, Check } from './callout';
13
- export { Latex } from './latex';
14
- export { API } from './api';
15
- export { Expandable } from './expandable';
16
- export { ResponseField, Properties, Property } from './open-api';
17
- export { Steps, Step } from './step';
18
- export { Table as table, Th as th, Td as td } from './table';
19
- export { UnorderedList as ul, OrderedList as ol, ListItem as li } from './list';
20
- export { APIPlayground } from './api-playground';
21
- export { WebSocketPlayground } from './websocket-playground';
22
- export { AsyncAPI } from './async-api';
23
- export { Source } from './source';
24
-
25
- export const wrapper = ({ children }: { children: preact.ComponentChildren }) => {
26
- const ref = useRef<HTMLDivElement>(null);
27
- const pathname = usePathname();
28
-
29
- useEffect(() => {
30
- if (ref.current) {
31
- // Hide the first h1 if it matches the title
32
- // This is to avoid having the same title twice in the navigation
33
- const title = completeFrontMatter.find(fm => fm.path === pathname)?.title;
34
- const h1 = ref.current.querySelector('h1') as HTMLHeadingElement;
35
- if (h1) {
36
- h1.hidden = title === h1.innerText;
37
- }
38
- }
39
- }, [pathname]);
40
-
41
- return <div className="flex flex-col w-full" ref={ref}>{children}</div>;
42
- };
43
-
44
-
45
- export const hr = () => <hr className="my-4 text-gray-500/25 dark:text-gray-200/25" />;
46
-
47
- export const br = () => <br />;