@clidey/dory 0.22.0 → 0.24.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.
- package/bin/dist/dory.d.ts +3 -0
- package/bin/dist/dory.d.ts.map +1 -0
- package/bin/dist/dory.js +337 -0
- package/bin/dist/dory.js.map +1 -0
- package/bin/dory.ts +287 -121
- package/dist/dory.json +5 -0
- package/dist/favicon.svg +1 -1
- package/dist/index.html +6 -6
- package/dist/introduction.mdx +2 -2
- package/dist/llms.txt +2 -2
- package/docs/dory.json +5 -0
- package/docs/favicon.svg +1 -1
- package/docs/introduction.mdx +2 -2
- package/package.json +16 -11
- package/src/app.css +2 -0
- package/src/components/dropdown.tsx +30 -26
- package/src/components/loading.tsx +6 -8
- package/src/components/navigation.tsx +8 -6
- package/src/components/notification.tsx +9 -93
- package/src/components/routes.tsx +1 -1
- package/src/components/search.tsx +31 -104
- package/src/components/store.ts +4 -1
- package/src/main.tsx +9 -5
- package/src/mdx/accordion.tsx +21 -28
- package/src/mdx/api-playground.tsx +68 -83
- package/src/mdx/api.tsx +21 -21
- package/src/mdx/async-api.tsx +15 -31
- package/src/mdx/callout.tsx +27 -43
- package/src/mdx/card.tsx +20 -14
- package/src/mdx/code.tsx +26 -26
- package/src/mdx/expandable.tsx +21 -25
- package/src/mdx/fence.tsx +2 -2
- package/src/mdx/list.tsx +2 -2
- package/src/mdx/open-api.tsx +31 -45
- package/src/mdx/table.tsx +8 -3
- package/src/mdx/tag.tsx +27 -40
- package/src/mdx/text.tsx +3 -2
- package/src/mdx/websocket-playground.tsx +150 -81
- package/src/theme.scss +50 -106
- package/src/types/config.ts +47 -0
- package/src/ui/header.tsx +12 -9
- package/src/ui/layout.tsx +5 -4
- package/src/ui/mobile-navigation.tsx +36 -63
- package/src/ui/table-of-content.tsx +3 -3
- package/src/utils/colors.ts +54 -0
- package/src/utils/fonts.ts +4 -1
- package/tsconfig.app.json +2 -1
- package/tsconfig.bin.json +11 -7
- package/tsconfig.node.json +2 -1
- package/vite.config.ts +2 -0
- package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/assets/__vite-browser-external-BIHI7g3E.js +0 -1
- package/dist/assets/_basePickBy-CsnA5_xx.js +0 -1
- package/dist/assets/_baseUniq-COwFna6s.js +0 -1
- package/dist/assets/api-playground-demo-Ct5XK2u1.js +0 -45
- package/dist/assets/api-playground-demo-vBae5R-d.js +0 -119
- package/dist/assets/arc-Dy4kITED.js +0 -1
- package/dist/assets/architectureDiagram-IEHRJDOE-BiaWQpzt.js +0 -36
- package/dist/assets/blockDiagram-JOT3LUYC-7LfUOsM7.js +0 -121
- package/dist/assets/c4Diagram-VJAJSXHY-Ca-3deDF.js +0 -10
- package/dist/assets/channel-j6jMzwSu.js +0 -1
- package/dist/assets/chunk-4BMEZGHF-Cln31Q_z.js +0 -1
- package/dist/assets/chunk-A2AXSNBT-Cj4U7K4I.js +0 -164
- package/dist/assets/chunk-AEK57VVT-1kn9120k.js +0 -220
- package/dist/assets/chunk-D6G4REZN-DMgQaOLS.js +0 -1
- package/dist/assets/chunk-RZ5BOZE2-DDd-DrSb.js +0 -1
- package/dist/assets/chunk-XZIHB7SX-sVdgMrEr.js +0 -1
- package/dist/assets/classDiagram-GIVACNV2-B9ObtIrc.js +0 -1
- package/dist/assets/classDiagram-v2-COTLJTTW-B9ObtIrc.js +0 -1
- package/dist/assets/clone-UOttdbrS.js +0 -1
- package/dist/assets/create-D-Wjvs-T.js +0 -6
- package/dist/assets/create-DpzlgYHc.js +0 -4
- package/dist/assets/cytoscape.esm-BY7v1xhs.js +0 -331
- package/dist/assets/dagre-OKDRZEBW-C4q12sCc.js +0 -4
- package/dist/assets/delete-DwAmDeAN.js +0 -4
- package/dist/assets/delete-cbziNMWs.js +0 -5
- package/dist/assets/diagram-SSKATNLV-BxNC6sGs.js +0 -43
- package/dist/assets/diagram-VNBRO52H-CukGDk3b.js +0 -24
- package/dist/assets/dory.jpeg +0 -0
- package/dist/assets/erDiagram-Q7BY3M3F-TiiVq0dv.js +0 -60
- package/dist/assets/favicon-Z67lNtJu.svg +0 -75
- package/dist/assets/features-6EEoDloV.js +0 -269
- package/dist/assets/features-EZwrzTnN.js +0 -441
- package/dist/assets/flowDiagram-4HSFHLVR-DykkGbol.js +0 -161
- package/dist/assets/ganttDiagram-APWFNJXF-Bqp95-S3.js +0 -257
- package/dist/assets/get-BeAg4Qrr.js +0 -5
- package/dist/assets/get-Dj1eDs2i.js +0 -4
- package/dist/assets/gitGraphDiagram-7IBYFJ6S-BiYVs9VI.js +0 -65
- package/dist/assets/graph-LkKKMaDZ.js +0 -1
- package/dist/assets/index-CGd7uPvh.css +0 -1
- package/dist/assets/index-vOROtq-e.js +0 -9596
- package/dist/assets/infoDiagram-PH2N3AL5-EA7h3wZa.js +0 -2
- package/dist/assets/init-Gi6I4Gst.js +0 -1
- package/dist/assets/introduction-CzXlzjWa.js +0 -38
- package/dist/assets/introduction-ylYJcPz3.js +0 -45
- package/dist/assets/journeyDiagram-U35MCT3I-BZiVuCZu.js +0 -138
- package/dist/assets/kanban-definition-NDS4AKOZ-SCdQ8OjR.js +0 -88
- package/dist/assets/layout-C9-9-M2q.js +0 -1
- package/dist/assets/linear-CTbdhYd1.js +0 -1
- package/dist/assets/mermaid.core-DUFqLK_I.js +0 -213
- package/dist/assets/mindmap-definition-ALO5MXBD-BPbKEbjk.js +0 -95
- package/dist/assets/ordinal-Cboi1Yqb.js +0 -1
- package/dist/assets/pieDiagram-IB7DONF6-DPg1sNm8.js +0 -30
- package/dist/assets/quadrantDiagram-7GDLP6J5-DmtJM50d.js +0 -7
- package/dist/assets/radar-MK3ICKWK-DnO5LA4B.js +0 -128
- package/dist/assets/receive-chat-message-B2jsY1P6.js +0 -4
- package/dist/assets/receive-chat-message-BeaC4eqS.js +0 -5
- package/dist/assets/receive-notifications-BouRLPFj.js +0 -4
- package/dist/assets/receive-notifications-DYnXRRBz.js +0 -5
- package/dist/assets/receive-presence-update-CRgeSUpk.js +0 -5
- package/dist/assets/receive-presence-update-UEm47KAG.js +0 -4
- package/dist/assets/requirementDiagram-KVF5MWMF-iNwUJLq2.js +0 -64
- package/dist/assets/sankeyDiagram-QLVOVGJD-DWLyAD59.js +0 -10
- package/dist/assets/send-chat-message-Bvf2XJiv.js +0 -5
- package/dist/assets/send-chat-message-FDmVETeD.js +0 -4
- package/dist/assets/send-presence-update-26clGQ0z.js +0 -5
- package/dist/assets/send-presence-update-DeywSKYu.js +0 -4
- package/dist/assets/sequenceDiagram-X6HHIX6F-HyRN2_g-.js +0 -122
- package/dist/assets/stateDiagram-DGXRK772-DdMr0V93.js +0 -1
- package/dist/assets/stateDiagram-v2-YXO3MK2T-D6kpXRiR.js +0 -1
- package/dist/assets/timeline-definition-BDJGKUSR-CDf8nWgC.js +0 -61
- package/dist/assets/update-BEeNDeXY.js +0 -4
- package/dist/assets/update-CykJMYvN.js +0 -5
- package/dist/assets/websocket-playground-demo-4pj7mj19.js +0 -135
- package/dist/assets/websocket-playground-demo-F71LN60e.js +0 -61
- package/dist/assets/xychartDiagram-VJFVF3MP-BY_uTq9r.js +0 -7
- package/docs/assets/dory.jpeg +0 -0
- package/src/components/dark-mode-toggle.tsx +0 -25
- package/src/index.css +0 -24
- package/src/utils/hooks.ts +0 -46
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
|
|
2
2
|
import { CheckIcon } from '@heroicons/react/24/outline'
|
|
3
3
|
import classNames from 'classnames'
|
|
4
|
-
import { PencilIcon, TrashIcon, XIcon } from 'lucide-react'
|
|
4
|
+
import { PencilIcon, TrashIcon, XIcon, PlusIcon, MessageCircleIcon } from 'lucide-react'
|
|
5
5
|
import { useCallback, useEffect, useRef, useState } from 'preact/hooks'
|
|
6
6
|
import Dropdown from '../components/dropdown'
|
|
7
7
|
import { Tag } from './tag'
|
|
8
8
|
import { PlayButton } from './api-playground'
|
|
9
|
+
import { Badge, Button, Card, EmptyState, Sheet, SheetContent, SheetHeader, SheetTitle, Input } from '@clidey/ux'
|
|
9
10
|
|
|
10
11
|
export interface WebSocketServer {
|
|
11
12
|
url: string;
|
|
@@ -156,39 +157,39 @@ export const HeadersTab = ({ wsConfig, setWsConfig }: HeadersTabProps) => {
|
|
|
156
157
|
value={hdr.key}
|
|
157
158
|
onChange={e => updateHeader(idx, 'key', (e.target as HTMLInputElement).value)}
|
|
158
159
|
placeholder="Header name"
|
|
159
|
-
className="w-32
|
|
160
|
+
className="w-32 text-sm"
|
|
160
161
|
/>
|
|
161
162
|
<Input
|
|
162
163
|
type="text"
|
|
163
164
|
value={hdr.value}
|
|
164
165
|
onChange={e => updateHeader(idx, 'value', (e.target as HTMLInputElement).value)}
|
|
165
166
|
placeholder="Header value"
|
|
166
|
-
className="flex-1
|
|
167
|
+
className="flex-1 text-sm"
|
|
167
168
|
/>
|
|
168
|
-
<
|
|
169
|
+
<Button onClick={() => saveHeader(idx)} variant="ghost" size="icon" className="text-white h-8 w-8">
|
|
169
170
|
<CheckIcon className="w-4 h-4" />
|
|
170
|
-
</
|
|
171
|
-
<
|
|
171
|
+
</Button>
|
|
172
|
+
<Button onClick={() => cancelEdit(idx)} variant="ghost" size="icon" className="text-white h-8 w-8">
|
|
172
173
|
<XIcon className="w-4 h-4" />
|
|
173
|
-
</
|
|
174
|
+
</Button>
|
|
174
175
|
</>
|
|
175
176
|
) : (
|
|
176
177
|
<>
|
|
177
178
|
<span className="text-sm text-white w-32 truncate">{hdr.key}</span>
|
|
178
179
|
<span className="text-sm text-white flex-1 truncate">{hdr.value}</span>
|
|
179
|
-
<
|
|
180
|
+
<Button onClick={() => editHeader(idx)} variant="ghost" size="icon" className="text-white h-8 w-8">
|
|
180
181
|
<PencilIcon className="w-4 h-4" />
|
|
181
|
-
</
|
|
182
|
-
<
|
|
182
|
+
</Button>
|
|
183
|
+
<Button onClick={() => removeHeader(idx)} variant="ghost" size="icon" className="text-red-400 h-8 w-8">
|
|
183
184
|
<TrashIcon className="w-4 h-4" />
|
|
184
|
-
</
|
|
185
|
+
</Button>
|
|
185
186
|
</>
|
|
186
187
|
)}
|
|
187
188
|
</div>
|
|
188
189
|
))}
|
|
189
|
-
<
|
|
190
|
-
|
|
191
|
-
</
|
|
190
|
+
<Button onClick={addEmptyHeaderRow} variant="ghost" size="sm" className="mt-2 w-fit">
|
|
191
|
+
<PlusIcon className="w-4 h-4" /> Add Header
|
|
192
|
+
</Button>
|
|
192
193
|
</div>
|
|
193
194
|
)
|
|
194
195
|
}
|
|
@@ -273,38 +274,39 @@ export const SubprotocolsTab = ({ subprotocols, setWsConfig }: SubprotocolsTabPr
|
|
|
273
274
|
value={s.value}
|
|
274
275
|
onChange={e => updateSubprotocol(i, (e.target as HTMLInputElement).value)}
|
|
275
276
|
placeholder="Subprotocol name"
|
|
276
|
-
className="flex-1
|
|
277
|
+
className="flex-1 text-sm"
|
|
277
278
|
/>
|
|
278
|
-
<
|
|
279
|
+
<Button onClick={() => saveSubprotocol(i)} variant="ghost" size="icon" className="text-white h-8 w-8">
|
|
279
280
|
<CheckIcon className="w-4 h-4" />
|
|
280
|
-
</
|
|
281
|
-
<
|
|
281
|
+
</Button>
|
|
282
|
+
<Button onClick={() => cancelEdit(i)} variant="ghost" size="icon" className="text-white h-8 w-8">
|
|
282
283
|
<XIcon className="w-4 h-4" />
|
|
283
|
-
</
|
|
284
|
+
</Button>
|
|
284
285
|
</>
|
|
285
286
|
) : (
|
|
286
287
|
<>
|
|
287
|
-
<span className="flex-1 truncate text-sm
|
|
288
|
-
<
|
|
288
|
+
<span className="flex-1 truncate text-sm">{s.value}</span>
|
|
289
|
+
<Button onClick={() => editSubprotocol(i)} variant="ghost" size="icon" className="text-white h-8 w-8">
|
|
289
290
|
<PencilIcon className="w-4 h-4" />
|
|
290
|
-
</
|
|
291
|
-
<
|
|
291
|
+
</Button>
|
|
292
|
+
<Button onClick={() => removeSubprotocol(i)} variant="ghost" size="icon" className="text-red-400 h-8 w-8">
|
|
292
293
|
<TrashIcon className="w-4 h-4" />
|
|
293
|
-
</
|
|
294
|
+
</Button>
|
|
294
295
|
</>
|
|
295
296
|
)}
|
|
296
297
|
</div>
|
|
297
298
|
))}
|
|
298
|
-
<
|
|
299
|
+
<Button onClick={addSubprotocolRow} variant="ghost" size="sm" className="text-sky-400 hover:text-sky-300 mt-2 self-start">
|
|
299
300
|
+ Add Subprotocol
|
|
300
|
-
</
|
|
301
|
+
</Button>
|
|
301
302
|
</div>
|
|
302
303
|
)
|
|
303
304
|
}
|
|
304
305
|
|
|
305
306
|
type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'error'
|
|
306
307
|
|
|
307
|
-
|
|
308
|
+
// Internal playground component that contains the actual WebSocket UI
|
|
309
|
+
function WebSocketPlaygroundInternal({
|
|
308
310
|
url,
|
|
309
311
|
title,
|
|
310
312
|
description,
|
|
@@ -478,10 +480,10 @@ export function WebSocketPlayground({
|
|
|
478
480
|
return (
|
|
479
481
|
<div className="my-6 overflow-hidden rounded-2xl">
|
|
480
482
|
{/* Header */}
|
|
481
|
-
<div className="flex min-h-[calc(--spacing(12)+1px)] flex-wrap items-start gap-x-4
|
|
483
|
+
<div className="flex min-h-[calc(--spacing(12)+1px)] flex-wrap items-start gap-x-4 px-4 pt-2 pb-4 justify-between">
|
|
482
484
|
<div className="flex items-center gap-3 pt-3">
|
|
483
485
|
<Tag variant="small">WS</Tag>
|
|
484
|
-
<span className="font-mono text-sm
|
|
486
|
+
<span className="font-mono text-sm">{title || url}</span>
|
|
485
487
|
<div className="flex items-center gap-2">
|
|
486
488
|
<div className={`w-2 h-2 rounded-full ${connectionState === 'connected' ? 'bg-green-400' : connectionState === 'connecting' ? 'bg-yellow-400' : connectionState === 'error' ? 'bg-red-400' : 'bg-zinc-400'}`} />
|
|
487
489
|
<span className={`text-xs ${getConnectionStatusColor()}`}>
|
|
@@ -490,11 +492,11 @@ export function WebSocketPlayground({
|
|
|
490
492
|
</div>
|
|
491
493
|
</div>
|
|
492
494
|
<div className="flex gap-2 ml-auto pt-3">
|
|
493
|
-
<
|
|
495
|
+
<Button
|
|
494
496
|
onClick={connectWebSocket}
|
|
495
497
|
disabled={connectionState === 'connecting' || connectionState === 'connected'}
|
|
496
498
|
className={classNames(
|
|
497
|
-
'flex items-center gap-2
|
|
499
|
+
'flex items-center gap-2',
|
|
498
500
|
connectionState === 'connecting' || connectionState === 'connected'
|
|
499
501
|
? 'bg-zinc-600 text-zinc-400 cursor-not-allowed'
|
|
500
502
|
: 'bg-green-600 text-white hover:bg-green-700'
|
|
@@ -506,34 +508,31 @@ export function WebSocketPlayground({
|
|
|
506
508
|
<PlayButton className="h-4 w-4" />
|
|
507
509
|
)}
|
|
508
510
|
{connectionState === 'connecting' ? 'Connecting...' : 'Connect'}
|
|
509
|
-
</
|
|
510
|
-
<
|
|
511
|
+
</Button>
|
|
512
|
+
<Button
|
|
511
513
|
onClick={disconnectWebSocket}
|
|
512
514
|
disabled={connectionState === 'disconnected'}
|
|
515
|
+
variant="destructive"
|
|
513
516
|
className={classNames(
|
|
514
|
-
'flex items-center gap-2
|
|
515
|
-
connectionState === 'disconnected'
|
|
516
|
-
? 'bg-zinc-600 text-zinc-400 cursor-not-allowed'
|
|
517
|
-
: 'bg-red-600 text-white hover:bg-red-700'
|
|
517
|
+
'flex items-center gap-2',
|
|
518
|
+
connectionState === 'disconnected' && 'bg-zinc-600 text-zinc-400 cursor-not-allowed'
|
|
518
519
|
)}
|
|
519
520
|
>
|
|
520
521
|
<DisconnectButton className="h-4 w-4" />
|
|
521
522
|
Disconnect
|
|
522
|
-
</
|
|
523
|
+
</Button>
|
|
523
524
|
</div>
|
|
524
525
|
</div>
|
|
525
526
|
|
|
526
527
|
{description && (
|
|
527
|
-
<
|
|
528
|
-
<p className="text-sm text-zinc-300">{description}</p>
|
|
529
|
-
</div>
|
|
528
|
+
<p className="text-sm px-4 py-3">{description}</p>
|
|
530
529
|
)}
|
|
531
530
|
|
|
532
531
|
<div className="flex flex-col lg:flex-row gap-4">
|
|
533
532
|
{/* Configuration */}
|
|
534
533
|
<div className="flex-1 min-w-0">
|
|
535
534
|
<div className="flex flex-col gap-2 p-4">
|
|
536
|
-
<label className="text-sm font-medium
|
|
535
|
+
<label className="text-sm font-medium">Server</label>
|
|
537
536
|
<Dropdown
|
|
538
537
|
buttonLabel={selectedServer?.description || selectedServer?.url || 'Select Server'}
|
|
539
538
|
items={servers.map(server => ({
|
|
@@ -544,9 +543,9 @@ export function WebSocketPlayground({
|
|
|
544
543
|
/>
|
|
545
544
|
</div>
|
|
546
545
|
|
|
547
|
-
<div
|
|
546
|
+
<div>
|
|
548
547
|
<TabGroup selectedIndex={selectedTab} onChange={setSelectedTab}>
|
|
549
|
-
<TabList className="flex
|
|
548
|
+
<TabList className="flex">
|
|
550
549
|
{tabs.map((tab) => (
|
|
551
550
|
<Tab
|
|
552
551
|
key={tab.key}
|
|
@@ -554,7 +553,7 @@ export function WebSocketPlayground({
|
|
|
554
553
|
classNames(
|
|
555
554
|
'px-4 py-3 text-sm font-medium transition border-b-2',
|
|
556
555
|
selected
|
|
557
|
-
? 'border-
|
|
556
|
+
? 'border-brand-foreground text-brand-foreground'
|
|
558
557
|
: 'border-transparent text-zinc-400 hover:text-zinc-300'
|
|
559
558
|
)
|
|
560
559
|
}
|
|
@@ -582,7 +581,7 @@ export function WebSocketPlayground({
|
|
|
582
581
|
{/* Auth Tab */}
|
|
583
582
|
<TabPanel className="p-4 space-y-4">
|
|
584
583
|
<div className="flex flex-col space-y-2">
|
|
585
|
-
<label className="text-sm font-medium
|
|
584
|
+
<label className="text-sm font-medium">Authentication Type</label>
|
|
586
585
|
<Dropdown
|
|
587
586
|
buttonLabel={auth.type === 'none' ? 'Select Auth Type' : auth.type.charAt(0).toUpperCase() + auth.type.slice(1)}
|
|
588
587
|
items={[
|
|
@@ -597,26 +596,26 @@ export function WebSocketPlayground({
|
|
|
597
596
|
|
|
598
597
|
{auth.type === 'bearer' && (
|
|
599
598
|
<div className="space-y-2">
|
|
600
|
-
<label className="text-sm font-medium
|
|
601
|
-
<
|
|
599
|
+
<label className="text-sm font-medium">Bearer Token</label>
|
|
600
|
+
<Input
|
|
602
601
|
type="password"
|
|
603
602
|
value={auth.token}
|
|
604
603
|
onChange={(e) => setAuth(prev => ({ ...prev, token: (e.target as HTMLInputElement).value }))}
|
|
605
604
|
placeholder="Enter bearer token..."
|
|
606
|
-
className="w-full
|
|
605
|
+
className="w-full text-sm"
|
|
607
606
|
/>
|
|
608
607
|
</div>
|
|
609
608
|
)}
|
|
610
609
|
|
|
611
610
|
{auth.type === 'apiKey' && (
|
|
612
611
|
<div className="space-y-2">
|
|
613
|
-
<label className="text-sm font-medium
|
|
614
|
-
<
|
|
612
|
+
<label className="text-sm font-medium">API Key</label>
|
|
613
|
+
<Input
|
|
615
614
|
type="password"
|
|
616
615
|
value={auth.apiKey}
|
|
617
616
|
onChange={(e) => setAuth(prev => ({ ...prev, apiKey: (e.target as HTMLInputElement).value }))}
|
|
618
617
|
placeholder="Enter API key..."
|
|
619
|
-
className="w-full
|
|
618
|
+
className="w-full text-sm"
|
|
620
619
|
/>
|
|
621
620
|
</div>
|
|
622
621
|
)}
|
|
@@ -624,23 +623,23 @@ export function WebSocketPlayground({
|
|
|
624
623
|
{auth.type === 'basic' && (
|
|
625
624
|
<div className="space-y-4">
|
|
626
625
|
<div className="space-y-2">
|
|
627
|
-
<label className="text-sm font-medium
|
|
628
|
-
<
|
|
626
|
+
<label className="text-sm font-medium">Username</label>
|
|
627
|
+
<Input
|
|
629
628
|
type="text"
|
|
630
629
|
value={auth.username}
|
|
631
630
|
onChange={(e) => setAuth(prev => ({ ...prev, username: (e.target as HTMLInputElement).value }))}
|
|
632
631
|
placeholder="Enter username..."
|
|
633
|
-
className="w-full
|
|
632
|
+
className="w-full text-sm"
|
|
634
633
|
/>
|
|
635
634
|
</div>
|
|
636
635
|
<div className="space-y-2">
|
|
637
|
-
<label className="text-sm font-medium
|
|
638
|
-
<
|
|
636
|
+
<label className="text-sm font-medium">Password</label>
|
|
637
|
+
<Input
|
|
639
638
|
type="password"
|
|
640
639
|
value={auth.password}
|
|
641
640
|
onChange={(e) => setAuth(prev => ({ ...prev, password: (e.target as HTMLInputElement).value }))}
|
|
642
641
|
placeholder="Enter password..."
|
|
643
|
-
className="w-full
|
|
642
|
+
className="w-full text-sm"
|
|
644
643
|
/>
|
|
645
644
|
</div>
|
|
646
645
|
</div>
|
|
@@ -653,24 +652,22 @@ export function WebSocketPlayground({
|
|
|
653
652
|
|
|
654
653
|
{/* Messages */}
|
|
655
654
|
<div className="flex-1 min-w-0">
|
|
656
|
-
<div
|
|
657
|
-
<div className="flex items-center justify-between px-4 py-3
|
|
658
|
-
<h3 className="text-sm font-semibold
|
|
659
|
-
<
|
|
655
|
+
<div>
|
|
656
|
+
<div className="flex items-center justify-between px-4 py-3">
|
|
657
|
+
<h3 className="text-sm font-semibold">Messages</h3>
|
|
658
|
+
<Button
|
|
660
659
|
onClick={clearMessages}
|
|
660
|
+
variant="ghost"
|
|
661
|
+
size="sm"
|
|
661
662
|
className="text-xs text-zinc-400 hover:text-zinc-300"
|
|
662
663
|
>
|
|
663
664
|
Clear
|
|
664
|
-
</
|
|
665
|
+
</Button>
|
|
665
666
|
</div>
|
|
666
667
|
|
|
667
668
|
<div className="flex flex-col h-64 overflow-y-auto p-4 space-y-2">
|
|
668
669
|
{messages.length === 0 ? (
|
|
669
|
-
<
|
|
670
|
-
<div className="text-zinc-400 text-sm">
|
|
671
|
-
Connect to start receiving messages
|
|
672
|
-
</div>
|
|
673
|
-
</div>
|
|
670
|
+
<EmptyState icon={<MessageCircleIcon className="h-5 w-5" />} title="No messages yet" description="Connect to start receiving messages" />
|
|
674
671
|
) : (
|
|
675
672
|
messages.map((msg) => (
|
|
676
673
|
<div
|
|
@@ -709,29 +706,26 @@ export function WebSocketPlayground({
|
|
|
709
706
|
</div>
|
|
710
707
|
|
|
711
708
|
{/* Send Message */}
|
|
712
|
-
<div className="
|
|
709
|
+
<div className="p-4">
|
|
713
710
|
<div className="flex gap-2">
|
|
714
|
-
<
|
|
711
|
+
<Input
|
|
715
712
|
type="text"
|
|
716
713
|
value={messageInput}
|
|
717
714
|
onChange={(e) => setMessageInput((e.target as HTMLInputElement).value)}
|
|
718
715
|
onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
|
|
719
716
|
placeholder="Enter message to send..."
|
|
720
717
|
disabled={connectionState !== 'connected'}
|
|
721
|
-
className="flex-1
|
|
718
|
+
className="flex-1 text-sm"
|
|
722
719
|
/>
|
|
723
|
-
<
|
|
720
|
+
<Button
|
|
724
721
|
onClick={sendMessage}
|
|
725
722
|
disabled={connectionState !== 'connected' || !messageInput.trim()}
|
|
726
|
-
className={classNames(
|
|
727
|
-
'
|
|
728
|
-
|
|
729
|
-
? 'bg-sky-600 text-white hover:bg-sky-700'
|
|
730
|
-
: 'bg-zinc-600 text-zinc-400 cursor-not-allowed'
|
|
731
|
-
)}
|
|
723
|
+
className={classNames({
|
|
724
|
+
'bg-sky-600 text-white hover:bg-sky-700': connectionState === 'connected' && messageInput.trim()
|
|
725
|
+
})}
|
|
732
726
|
>
|
|
733
727
|
Send
|
|
734
|
-
</
|
|
728
|
+
</Button>
|
|
735
729
|
</div>
|
|
736
730
|
</div>
|
|
737
731
|
</div>
|
|
@@ -739,7 +733,7 @@ export function WebSocketPlayground({
|
|
|
739
733
|
</div>
|
|
740
734
|
|
|
741
735
|
{error && (
|
|
742
|
-
<div className="
|
|
736
|
+
<div className="p-4">
|
|
743
737
|
<div className="flex items-center gap-2">
|
|
744
738
|
<span className="inline-flex items-center rounded-full bg-rose-500/10 px-2 py-1 text-xs font-medium text-rose-400 ring-1 ring-rose-500/20">
|
|
745
739
|
Error
|
|
@@ -752,4 +746,79 @@ export function WebSocketPlayground({
|
|
|
752
746
|
)}
|
|
753
747
|
</div>
|
|
754
748
|
)
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// Main exported component with Sheet wrapper
|
|
752
|
+
export function WebSocketPlayground(props: WebSocketPlaygroundProps) {
|
|
753
|
+
const [showPlayground, setShowPlayground] = useState(false)
|
|
754
|
+
|
|
755
|
+
const handleShowPlayground = () => {
|
|
756
|
+
setShowPlayground(true)
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
return (
|
|
760
|
+
<div className="max-w-none w-full my-6">
|
|
761
|
+
<Sheet open={showPlayground} onOpenChange={setShowPlayground} modal={true}>
|
|
762
|
+
<SheetContent side="bottom" className="h-[90vh] w-full overflow-y-auto p-8">
|
|
763
|
+
<SheetHeader className="p-0">
|
|
764
|
+
<SheetTitle>WebSocket Playground</SheetTitle>
|
|
765
|
+
</SheetHeader>
|
|
766
|
+
<WebSocketPlaygroundInternal {...props} />
|
|
767
|
+
</SheetContent>
|
|
768
|
+
</Sheet>
|
|
769
|
+
|
|
770
|
+
<Card className="overflow-hidden py-0 border-1 border-black/10">
|
|
771
|
+
<div className="flex items-center justify-between px-4 py-3">
|
|
772
|
+
<div className="flex items-center gap-3">
|
|
773
|
+
<Tag variant="small">WS</Tag>
|
|
774
|
+
<span className="font-mono text-sm">{props.title || props.url}</span>
|
|
775
|
+
</div>
|
|
776
|
+
<Button
|
|
777
|
+
onClick={handleShowPlayground}
|
|
778
|
+
className="flex items-center gap-2"
|
|
779
|
+
>
|
|
780
|
+
Try
|
|
781
|
+
<PlayButton className="h-4 w-4" />
|
|
782
|
+
</Button>
|
|
783
|
+
</div>
|
|
784
|
+
|
|
785
|
+
{props.description && (
|
|
786
|
+
<p className="text-sm px-4 py-3">{props.description}</p>
|
|
787
|
+
)}
|
|
788
|
+
|
|
789
|
+
<div className="px-4 py-3">
|
|
790
|
+
<div className="flex flex-col gap-2">
|
|
791
|
+
<div className="flex items-center gap-2">
|
|
792
|
+
<span className="text-xs font-medium text-zinc-400">Endpoint:</span>
|
|
793
|
+
<Badge>
|
|
794
|
+
{props.servers?.[0]?.url || 'ws://localhost'}{props.url}
|
|
795
|
+
</Badge>
|
|
796
|
+
</div>
|
|
797
|
+
|
|
798
|
+
{props.subprotocols && props.subprotocols.length > 0 && (
|
|
799
|
+
<div className="flex items-center gap-2">
|
|
800
|
+
<span className="text-xs font-medium text-zinc-400">Subprotocols:</span>
|
|
801
|
+
<div className="flex gap-1">
|
|
802
|
+
{props.subprotocols.map((protocol, idx) => (
|
|
803
|
+
<Badge key={idx}>
|
|
804
|
+
{protocol}
|
|
805
|
+
</Badge>
|
|
806
|
+
))}
|
|
807
|
+
</div>
|
|
808
|
+
</div>
|
|
809
|
+
)}
|
|
810
|
+
|
|
811
|
+
{props.authType && props.authType !== 'none' && (
|
|
812
|
+
<div className="flex items-center gap-2">
|
|
813
|
+
<span className="text-xs font-medium text-zinc-400">Authentication:</span>
|
|
814
|
+
<Badge>
|
|
815
|
+
{props.authType}
|
|
816
|
+
</Badge>
|
|
817
|
+
</div>
|
|
818
|
+
)}
|
|
819
|
+
</div>
|
|
820
|
+
</div>
|
|
821
|
+
</Card>
|
|
822
|
+
</div>
|
|
823
|
+
)
|
|
755
824
|
}
|
package/src/theme.scss
CHANGED
|
@@ -1,124 +1,68 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
:root {
|
|
2
|
+
font-synthesis: none;
|
|
3
|
+
text-rendering: optimizeLegibility;
|
|
4
|
+
-webkit-font-smoothing: antialiased;
|
|
5
|
+
-moz-osx-font-smoothing: grayscale;
|
|
6
|
+
|
|
7
|
+
// Brand colors (dynamically set from dory.json via loadColors())
|
|
8
|
+
// These variables are set at runtime:
|
|
9
|
+
// --brand-primary: primary color
|
|
10
|
+
// --brand-light: light mode accent
|
|
11
|
+
// --brand-dark: dark mode accent
|
|
12
|
+
// --brand-foreground: legacy/fallback (set to primary)
|
|
13
|
+
|
|
14
|
+
// Default fallback colors (will be overridden by loadColors())
|
|
15
|
+
--brand-foreground: #0ea5e9;
|
|
16
|
+
--brand-primary: #0ea5e9;
|
|
17
|
+
--brand-light: #38bdf8;
|
|
18
|
+
--brand-dark: #0284c7;
|
|
19
|
+
|
|
20
|
+
// ShadCN/clidey/ux compatible primary color
|
|
21
|
+
// Using light color for light mode
|
|
22
|
+
--primary: var(--brand-light);
|
|
23
|
+
--primary-rgb: var(--brand-light-rgb);
|
|
3
24
|
}
|
|
4
25
|
|
|
5
|
-
|
|
6
|
-
|
|
26
|
+
// Dark mode overrides
|
|
27
|
+
:root.dark {
|
|
28
|
+
// Use dark color for dark mode
|
|
29
|
+
--primary: var(--brand-dark);
|
|
30
|
+
--primary-rgb: var(--brand-dark-rgb);
|
|
7
31
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
color: #000000 !important;
|
|
12
|
-
font-size: 12px !important;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.mermaid rect {
|
|
16
|
-
fill: #f8f8f8 !important;
|
|
17
|
-
stroke: #333333 !important;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.mermaid p {
|
|
21
|
-
color: #000000 !important;
|
|
32
|
+
|
|
33
|
+
article h2:first-of-type {
|
|
34
|
+
display: none;
|
|
22
35
|
}
|
|
23
36
|
|
|
24
|
-
|
|
25
|
-
|
|
37
|
+
article hr:first-of-type {
|
|
38
|
+
display: none;
|
|
26
39
|
}
|
|
27
40
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
article img {
|
|
42
|
+
margin-top: 1rem;
|
|
43
|
+
margin-bottom: 1rem;
|
|
31
44
|
}
|
|
32
45
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
46
|
+
[data-testid="header-actions"] button,
|
|
47
|
+
[data-slot="dropdown-menu-content"] {
|
|
48
|
+
border-color: rgba(0, 0, 0, 0.1);
|
|
36
49
|
}
|
|
37
50
|
|
|
38
|
-
|
|
39
|
-
|
|
51
|
+
[data-slot="search-input-wrapper"] {
|
|
52
|
+
font-size: 12px;
|
|
53
|
+
outline: none;
|
|
40
54
|
}
|
|
41
55
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
stroke: #999999 !important;
|
|
45
|
-
color: #000000 !important;
|
|
56
|
+
[data-slot="search-input"] {
|
|
57
|
+
font-size: 12px;
|
|
46
58
|
}
|
|
47
59
|
|
|
48
|
-
|
|
49
|
-
|
|
60
|
+
[data-slot="search-input-wrapper"]:focus-within {
|
|
61
|
+
outline: none !important;
|
|
50
62
|
}
|
|
51
63
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
background-color: #1e1e1e !important;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
h1, h2, h3, h4, h5, h6, p, li, th, td {
|
|
60
|
-
color: #ffffff !important;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.mermaid {
|
|
64
|
-
background-color: #1e1e1e !important;
|
|
65
|
-
color: #ffffff !important;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.mermaid rect {
|
|
69
|
-
fill: #2a2a2a !important;
|
|
70
|
-
stroke: #aaaaaa !important;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.mermaid p {
|
|
74
|
-
color: #ffffff !important;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.mermaid path {
|
|
78
|
-
stroke: #cccccc !important;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.mermaid p {
|
|
82
|
-
background-color: #2a2a2a !important;
|
|
83
|
-
color: #ffffff !important;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.mermaid rect,
|
|
87
|
-
.mermaid polygon,
|
|
88
|
-
.mermaid circle,
|
|
89
|
-
.mermaid ellipse {
|
|
90
|
-
fill: #2a2a2a !important;
|
|
91
|
-
stroke: #444444 !important;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.mermaid p, .mermaid text, .mermaid text > tspan {
|
|
95
|
-
color: #ffffff !important;
|
|
96
|
-
fill: #ffffff !important;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.mermaid line {
|
|
100
|
-
stroke: #444444 !important;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.mermaid .note {
|
|
104
|
-
fill: #2a2a2a !important;
|
|
105
|
-
stroke: #444444 !important;
|
|
106
|
-
color: #ffffff !important;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
.docucod-mdx-code {
|
|
110
|
-
background-color: #2a2a2a !important;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.docucod-mdx-code-group {
|
|
114
|
-
background-color: #2a2a2a !important;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.docucod-mdx-code-group-header {
|
|
118
|
-
background-color: #2a2a2a !important;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.prism-code {
|
|
122
|
-
background-color: transparent !important;
|
|
123
|
-
}
|
|
64
|
+
[role="dialog"] [data-slot="search-input-wrapper"]:focus-within {
|
|
65
|
+
outline: none !important;
|
|
66
|
+
border: 0px;
|
|
67
|
+
box-shadow: none !important;
|
|
124
68
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript interfaces for dory.json configuration
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface DoryColors {
|
|
6
|
+
primary: string;
|
|
7
|
+
light: string;
|
|
8
|
+
dark: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface DoryFonts {
|
|
12
|
+
family: string;
|
|
13
|
+
source: string;
|
|
14
|
+
format: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface DoryLogo {
|
|
18
|
+
light: string;
|
|
19
|
+
dark: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface DoryNavigationPage {
|
|
23
|
+
[key: string]: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface DoryNavigationGroup {
|
|
27
|
+
group: string;
|
|
28
|
+
pages: string[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface DoryNavigationTab {
|
|
32
|
+
tab: string;
|
|
33
|
+
groups: DoryNavigationGroup[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface DoryNavigation {
|
|
37
|
+
tabs: DoryNavigationTab[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface DoryConfig {
|
|
41
|
+
name: string;
|
|
42
|
+
favicon: string;
|
|
43
|
+
colors?: DoryColors;
|
|
44
|
+
fonts?: DoryFonts;
|
|
45
|
+
navigation: DoryNavigation;
|
|
46
|
+
logo: DoryLogo;
|
|
47
|
+
}
|