@redocly/marketing-pages 0.1.16 → 0.1.17
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/dist/pages/editor/components/EditorPanel.d.ts +14 -0
- package/dist/pages/editor/components/EditorPanel.js +1 -0
- package/dist/pages/editor/components/EmptyState.d.ts +7 -0
- package/dist/pages/editor/components/EmptyState.js +31 -0
- package/dist/pages/editor/components/Page.d.ts +2 -0
- package/dist/pages/editor/components/Page.js +59 -0
- package/dist/pages/editor/components/PreviewPanel.d.ts +11 -0
- package/dist/pages/editor/components/PreviewPanel.js +20 -0
- package/dist/pages/editor/components/ProblemsPanel.d.ts +10 -0
- package/dist/pages/editor/components/ProblemsPanel.js +71 -0
- package/dist/pages/editor/components/Toolbar.d.ts +10 -0
- package/dist/pages/editor/components/Toolbar.js +50 -0
- package/dist/pages/editor/constants/editorConfig.d.ts +7 -0
- package/dist/pages/editor/constants/editorConfig.js +1 -0
- package/dist/pages/editor/editor.page.d.ts +8 -0
- package/dist/pages/editor/editor.page.js +1 -0
- package/dist/pages/editor/hooks/useColorMode.d.ts +1 -0
- package/dist/pages/editor/hooks/useColorMode.js +1 -0
- package/dist/pages/editor/hooks/useEditorState.d.ts +18 -0
- package/dist/pages/editor/hooks/useEditorState.js +1 -0
- package/dist/pages/editor/hooks/useFileOperations.d.ts +13 -0
- package/dist/pages/editor/hooks/useFileOperations.js +1 -0
- package/dist/pages/editor/hooks/useMonacoEditor.d.ts +12 -0
- package/dist/pages/editor/hooks/useMonacoEditor.js +1 -0
- package/dist/pages/editor/hooks/useOpenApiValidation.d.ts +14 -0
- package/dist/pages/editor/hooks/useOpenApiValidation.js +1 -0
- package/dist/pages/editor/services/languageServerService.d.ts +52 -0
- package/dist/pages/editor/services/languageServerService.js +3 -0
- package/dist/pages/editor/templates/defaultOpenapiTemplate.d.ts +1 -0
- package/dist/pages/editor/templates/defaultOpenapiTemplate.js +22 -0
- package/dist/pages/editor/utils/download.d.ts +1 -0
- package/dist/pages/editor/utils/download.js +1 -0
- package/dist/pages/editor-preview/editor-preview.page.d.ts +6 -0
- package/dist/pages/editor-preview/editor-preview.page.js +1 -0
- package/package.json +14 -8
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
3
|
+
interface EditorPanelProps {
|
|
4
|
+
value: string;
|
|
5
|
+
onChange: (value: string | undefined) => void;
|
|
6
|
+
onValidationUpdate?: (errors: Monaco.editor.IMarkerData[], value: string | undefined) => void;
|
|
7
|
+
hideWarnings: boolean;
|
|
8
|
+
gotoPosition?: {
|
|
9
|
+
line: number;
|
|
10
|
+
column: number;
|
|
11
|
+
} | null;
|
|
12
|
+
}
|
|
13
|
+
declare const EditorPanel: React.FC<EditorPanelProps>;
|
|
14
|
+
export default EditorPanel;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as t from"react";import f from"@monaco-editor/react";import{useMonacoEditor as s}from"../hooks/useMonacoEditor";import{DEFAULT_EDITOR_OPTIONS as d,EDITOR_LANGUAGE as p,EDITOR_THEMES as C}from"../constants/editorConfig";const I=({value:r,onChange:l,onValidationUpdate:o,hideWarnings:u,gotoPosition:e})=>{const[c,i]=t.useState(!1);t.useEffect(()=>i(!0),[]);const{activeColorMode:a,handleEditorDidMount:m,editorRef:n}=s({onValidationUpdate:o,hideWarnings:u,onClick:E=>{console.log("Editor clicked at position:",E)}});return t.useEffect(()=>{e&&n.current&&(n.current.revealPositionInCenter({lineNumber:e.line,column:e.column}),n.current.setPosition({lineNumber:e.line,column:e.column}),n.current.focus())},[e,n]),c?t.createElement(f,{language:p,theme:C[a],value:r,options:d,onChange:l,onMount:m}):null};var O=I;export{O as default};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface EmptyStateProps {
|
|
3
|
+
onTemplateClick?: () => void;
|
|
4
|
+
onUploadClick?: (content: string, fileName: string) => void;
|
|
5
|
+
}
|
|
6
|
+
export default function EmptyState({ onTemplateClick, onUploadClick }: EmptyStateProps): React.JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import e from"react";import t from"styled-components";import{Button as n}from"@redocly/theme/components/Button/Button";function o({onTemplateClick:i,onUploadClick:r}){return e.createElement(l,null,e.createElement(a,null),e.createElement(c,null,"Redocly Editor"),e.createElement(p,null,"Write, test, and preview your API references in a fully interactive environment. Use real-time rendering to build and refine your docs before publishing."),e.createElement(m,null,e.createElement(n,{onClick:i},"Use template"),e.createElement(n,{variant:"outlined",onClick:r},"Upload file")))}const l=t.div`
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
align-items: center;
|
|
5
|
+
justify-content: center;
|
|
6
|
+
height: 100%;
|
|
7
|
+
padding: 24px;
|
|
8
|
+
text-align: center;
|
|
9
|
+
`,a=t.div`
|
|
10
|
+
width: 160px;
|
|
11
|
+
height: 160px;
|
|
12
|
+
border-radius: 12px;
|
|
13
|
+
background-color: #f5f5f7;
|
|
14
|
+
margin-bottom: 24px;
|
|
15
|
+
`,c=t.h2`
|
|
16
|
+
margin: 0 0 12px 0;
|
|
17
|
+
font-size: 20px;
|
|
18
|
+
font-weight: 600;
|
|
19
|
+
color: var(--text-color-primary);
|
|
20
|
+
`,p=t.p`
|
|
21
|
+
max-width: 560px;
|
|
22
|
+
margin: 0 0 24px 0;
|
|
23
|
+
font-size: 15px;
|
|
24
|
+
line-height: 1.45;
|
|
25
|
+
color: #4b5563;
|
|
26
|
+
`,m=t.div`
|
|
27
|
+
display: flex;
|
|
28
|
+
gap: 8px;
|
|
29
|
+
`,f=t.span`
|
|
30
|
+
font-size: 10px;
|
|
31
|
+
`;export{o as default};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import r from"styled-components";import e from"react";import{Panel as t,PanelGroup as f,PanelResizeHandle as h}from"react-resizable-panels";import{useEditorState as L}from"../hooks/useEditorState";import{useOpenApiValidation as O}from"../hooks/useOpenApiValidation";import{useFileOperations as W}from"../hooks/useFileOperations";import H from"./EditorPanel";import{ProblemsPanel as N}from"./ProblemsPanel";import T from"./Toolbar";import G from"./PreviewPanel";function J(){const[v,g]=e.useState(!1);e.useEffect(()=>g(!0),[]);const{value:a,setValue:d,validatedValue:b,setValidatedValue:E,validationErrors:q,setValidationErrors:c,fileName:B,setFileName:P,parsedErrors:z,hasStructErrors:m,hideWarnings:p,setHideWarnings:x}=L(),{definition:y,hasRenderedOnce:C,setHasRenderedOnce:k}=O({validatedValue:b,hasStructErrors:m}),[w,S]=e.useState(null),[l,u]=e.useState(!0),n=e.useRef(null),o=W({setValue:d,setFileName:P,setHasRenderedOnce:k,setValidationErrors:c}),V=(i,s)=>{c(i),E(s)},R=(i,s)=>{S({line:i,column:s}),l&&n.current?.expand()},D=()=>o.handleDownloadYaml(a),F=()=>o.handleDownloadJson(a);return e.createElement(Y,null,e.createElement(U,{direction:"horizontal"},e.createElement(A,{defaultSize:50,minSize:20},e.createElement(T,{onFileLoad:o.handleFileLoad,onDownloadYamlClick:D,onDownloadJsonClick:F,hideWarnings:p,onHideWarningsChange:x}),e.createElement(I,null,e.createElement(f,{direction:"vertical"},e.createElement(t,{defaultSize:95},e.createElement(H,{value:a,onChange:d,onValidationUpdate:V,hideWarnings:p,gotoPosition:w})),e.createElement(h,{className:"resize-handle-horizontal",style:{display:l?"none":"block"}}),e.createElement(t,{ref:n,collapsible:!0,collapsedSize:5,defaultSize:5,minSize:20,onCollapse:u.bind(null,!0),onExpand:u.bind(null,!1)},e.createElement(N,{problems:z,onProblemClick:R,isCollapsed:l,onToggle:()=>{l?n.current?.expand():n.current?.collapse()}}))))),e.createElement(h,{className:"resize-handle"}),e.createElement(j,{defaultSize:50,minSize:20,collapsible:!0,collapsedSize:0},v&&e.createElement(G,{definition:y,rawValue:a,hasRenderedOnce:C,hasStructErrors:m,onTemplateClick:o.handleTemplateClick,onFileLoad:o.handleFileLoad}))))}const Y=r.div`
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
height: calc(100vh - var(--navbar-height));
|
|
5
|
+
|
|
6
|
+
background-color: var(--bg-color);
|
|
7
|
+
color: var(--text-color-primary);
|
|
8
|
+
|
|
9
|
+
[data-component-name='Layout/PageLayout']:has(&) + div + footer {
|
|
10
|
+
display: none;
|
|
11
|
+
}
|
|
12
|
+
`,U=r(f)`
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-grow: 1;
|
|
15
|
+
height: 100%;
|
|
16
|
+
overflow: visible;
|
|
17
|
+
|
|
18
|
+
.resize-handle {
|
|
19
|
+
width: 8px;
|
|
20
|
+
background-color: var(--border-color-primary);
|
|
21
|
+
cursor: col-resize;
|
|
22
|
+
transition: background-color 0.2s ease;
|
|
23
|
+
|
|
24
|
+
&:hover {
|
|
25
|
+
background-color: var(--color-primary-variant);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.resize-handle-horizontal {
|
|
30
|
+
height: 8px;
|
|
31
|
+
background-color: var(--border-color-primary);
|
|
32
|
+
cursor: row-resize;
|
|
33
|
+
transition: background-color 0.2s ease;
|
|
34
|
+
|
|
35
|
+
&:hover {
|
|
36
|
+
background-color: var(--color-primary-variant);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
`,A=r(t)`
|
|
40
|
+
flex: 2;
|
|
41
|
+
display: flex;
|
|
42
|
+
flex-direction: column;
|
|
43
|
+
overflow: visible;
|
|
44
|
+
|
|
45
|
+
.monaco-editor {
|
|
46
|
+
--vscode-editor-background: var(--layer-color);
|
|
47
|
+
--vscode-editorGutter-background: var(--layer-color);
|
|
48
|
+
}
|
|
49
|
+
`,I=r.div`
|
|
50
|
+
flex: 1;
|
|
51
|
+
min-height: 0;
|
|
52
|
+
display: flex;
|
|
53
|
+
`,j=r(t)`
|
|
54
|
+
flex: 3;
|
|
55
|
+
position: relative;
|
|
56
|
+
border-left: 1px solid var(--border-color-primary);
|
|
57
|
+
--sidebar-width: 0px;
|
|
58
|
+
--panel-gap-horizontal: var(--spacing-md);
|
|
59
|
+
`;export{J as default};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
interface PreviewPanelProps {
|
|
3
|
+
definition: any | null;
|
|
4
|
+
rawValue: string;
|
|
5
|
+
hasRenderedOnce: boolean;
|
|
6
|
+
hasStructErrors: boolean;
|
|
7
|
+
onTemplateClick: () => void;
|
|
8
|
+
onFileLoad: (content: string, fileName: string) => void;
|
|
9
|
+
}
|
|
10
|
+
declare const PreviewPanel: React.FC<PreviewPanelProps>;
|
|
11
|
+
export default PreviewPanel;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import*as e from"react";import d from"styled-components";import{useEffect as o,useRef as i}from"react";import R from"./EmptyState";import{useColorMode as b}from"../hooks/useColorMode";const I=d.div`
|
|
2
|
+
position: absolute;
|
|
3
|
+
top: 0;
|
|
4
|
+
left: 0;
|
|
5
|
+
right: 0;
|
|
6
|
+
background-color: rgba(255, 235, 238, 0.95);
|
|
7
|
+
color: #5c2121;
|
|
8
|
+
padding: 8px 16px;
|
|
9
|
+
border-bottom: 1px solid #f5c6cb;
|
|
10
|
+
text-align: center;
|
|
11
|
+
font-size: 0.9em;
|
|
12
|
+
z-index: 10;
|
|
13
|
+
`,x=d.iframe`
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: 100%;
|
|
16
|
+
border: none;
|
|
17
|
+
`,M=({definition:s,rawValue:l,hasStructErrors:g,onTemplateClick:h,onFileLoad:y})=>{const f=i(null),n=s||f.current,u=b(),v=i(null),t=i(null),[a,w]=e.useState(!1),[E,S]=e.useState(0),m=i(!1);o(()=>{const c=r=>{r.data?.type!=="scroll-sync"||r.data?.source==="preview"||!t.current||m.current||(m.current=!0,t.current.postMessage(r.data,"*"),setTimeout(()=>{m.current=!1},50))};return window.addEventListener("message",c),()=>window.removeEventListener("message",c)},[]),o(()=>{const c=r=>{t.current=r,r.updateDefinition(n),w(!0),setTimeout(()=>{r.postMessage({type:"theme-change",theme:u},"*")},100)};window.onReady=c},[n]),o(()=>{s&&(f.current=s)},[s]),o(()=>{t.current&&a&&t.current.updateDefinition(n)},[n,a]),o(()=>{t.current&&a&&t.current.postMessage({type:"theme-change",theme:u},"*")},[u,a]);const p=g&&e.createElement(I,null,"Preview is showing the last valid version. The current content has structural errors. Please check editor messages.")||null;return!l||typeof l!="string"||l.trim()===""?e.createElement(R,{onTemplateClick:h,onUploadClick:y}):n?e.createElement(e.Fragment,null,p,e.createElement(P,null,e.createElement(x,{key:E,ref:v,title:"API Documentation Preview",src:"/preview",onLoad:()=>{}}))):p||"Loading..."};var L=M;const P=d.div`
|
|
18
|
+
height: 100%;
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
`;export{L as default};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { editor as MonacoEditor } from 'monaco-editor';
|
|
3
|
+
interface ProblemsPanelProps {
|
|
4
|
+
problems: MonacoEditor.IMarkerData[];
|
|
5
|
+
onProblemClick: (line: number, column: number) => void;
|
|
6
|
+
isCollapsed: boolean;
|
|
7
|
+
onToggle: () => void;
|
|
8
|
+
}
|
|
9
|
+
export declare const ProblemsPanel: React.FC<ProblemsPanelProps>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import*as e from"react";import n from"styled-components";import{ChevronDownIcon as b}from"@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon";import{ChevronUpIcon as k}from"@redocly/theme/icons/ChevronUpIcon/ChevronUpIcon";const E={8:"Error",4:"Warning",2:"Info",1:"Hint"},h={8:"var(--color-error)",4:"var(--color-warning)",2:"var(--color-info)",1:"var(--color-info)"},T=({problems:o,onProblemClick:m,isCollapsed:a,onToggle:v})=>{const[r,f]=e.useState({key:"severity",direction:"descending"}),p=e.useMemo(()=>{let t=[...o];return r!==null&&t.sort((i,c)=>r.key==="line"?i.startLineNumber<c.startLineNumber?r.direction==="ascending"?-1:1:i.startLineNumber>c.startLineNumber?r.direction==="ascending"?1:-1:0:i[r.key]<c[r.key]?r.direction==="ascending"?-1:1:i[r.key]>c[r.key]?r.direction==="ascending"?1:-1:0),t},[o,r]),s=t=>{let i="ascending";r&&r.key===t&&r.direction==="ascending"&&(i="descending"),f({key:t,direction:i})},y=o.filter(t=>t.severity===8).length,x=o.filter(t=>t.severity===4).length;return e.createElement(C,{$collapsed:a},e.createElement(w,{onClick:v},e.createElement($,null,"Problems ",o.length,e.createElement(L,null,"(",e.createElement(d,{color:"var(--color-error)"},y," Errors"),e.createElement(d,{color:"var(--color-warning)"},x," Warnings"),")")),a?e.createElement(k,null):e.createElement(b,null)),!a&&e.createElement(S,null,e.createElement(g,null,e.createElement(l,{onClick:()=>s("severity")},"Severity ",r?.key==="severity"?r?.direction==="ascending"?"\u2191":"\u2193":""),e.createElement(l,{onClick:()=>s("message")},"Message ",r?.key==="message"?r?.direction==="ascending"?"\u2191":"\u2193":""),e.createElement(l,{onClick:()=>s("line")},"Line ",r?.key==="line"?r?.direction==="ascending"?"\u2191":"\u2193":"")),e.createElement(P,null,p.map((t,i)=>e.createElement(u,{key:i,onClick:()=>m(t.startLineNumber,t.startColumn)},e.createElement(l,null,e.createElement(z,{color:h[t.severity]},E[t.severity])),e.createElement(l,null,t.message),e.createElement(l,null,t.startLineNumber,":",t.startColumn))))))},C=n.div`
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
height: ${o=>o.$collapsed?"34px":"100%"};
|
|
5
|
+
max-height: ${o=>o.$collapsed?"34px":"none"};
|
|
6
|
+
background-color: var(--bg-color);
|
|
7
|
+
`,w=n.div`
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
justify-content: space-between;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
height: 34px;
|
|
13
|
+
padding: 0 12px;
|
|
14
|
+
border-top: 1px solid var(--border-color-primary);
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
user-select: none;
|
|
17
|
+
`,$=n.div`
|
|
18
|
+
font-size: 0.875rem;
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
gap: 16px;
|
|
22
|
+
`,L=n.div`
|
|
23
|
+
display: flex;
|
|
24
|
+
gap: 8px;
|
|
25
|
+
`,d=n.span`
|
|
26
|
+
color: ${o=>o.color};
|
|
27
|
+
`,S=n.div`
|
|
28
|
+
flex-grow: 1;
|
|
29
|
+
overflow: auto;
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
font-size: var(--font-size-sm);
|
|
33
|
+
`,N="100px 1fr 100px 100px",u=n.div`
|
|
34
|
+
display: grid;
|
|
35
|
+
grid-template-columns: ${N};
|
|
36
|
+
border-bottom: 1px solid var(--border-color-primary);
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
&:hover {
|
|
39
|
+
background-color: var(--layer-color);
|
|
40
|
+
}
|
|
41
|
+
`,g=n(u)`
|
|
42
|
+
position: sticky;
|
|
43
|
+
top: 0;
|
|
44
|
+
background-color: var(--bg-color);
|
|
45
|
+
font-weight: bold;
|
|
46
|
+
border-bottom-width: 2px;
|
|
47
|
+
cursor: default;
|
|
48
|
+
|
|
49
|
+
&:hover {
|
|
50
|
+
background-color: var(--bg-color);
|
|
51
|
+
}
|
|
52
|
+
`,P=n.div`
|
|
53
|
+
overflow-y: auto;
|
|
54
|
+
`,l=n.div`
|
|
55
|
+
padding: 6px 12px;
|
|
56
|
+
text-align: left;
|
|
57
|
+
white-space: nowrap;
|
|
58
|
+
overflow: hidden;
|
|
59
|
+
text-overflow: ellipsis;
|
|
60
|
+
|
|
61
|
+
${g} & {
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
user-select: none;
|
|
64
|
+
&:hover {
|
|
65
|
+
background-color: var(--lay);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
`,z=n.span`
|
|
69
|
+
color: ${o=>o.color};
|
|
70
|
+
font-weight: bold;
|
|
71
|
+
`;export{T as ProblemsPanel};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface ToolbarProps {
|
|
3
|
+
onFileLoad: (content: string, fileName: string) => void;
|
|
4
|
+
onDownloadYamlClick: () => void;
|
|
5
|
+
onDownloadJsonClick: () => void;
|
|
6
|
+
hideWarnings: boolean;
|
|
7
|
+
onHideWarningsChange: (hide: boolean) => void;
|
|
8
|
+
}
|
|
9
|
+
export default function Toolbar({ hideWarnings, onHideWarningsChange, onDownloadYamlClick, onDownloadJsonClick, onFileLoad }: ToolbarProps): React.JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import e,{useRef as v,useState as E}from"react";import o from"styled-components";import{Button as i}from"@redocly/theme/components/Button/Button";import{DownloadIcon as p}from"@redocly/theme/icons/DownloadIcon/DownloadIcon";import{ChevronDownIcon as k}from"@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon";function C({hideWarnings:m,onHideWarningsChange:f,onDownloadYamlClick:c,onDownloadJsonClick:u,onFileLoad:g}){const d=v(null),[x,t]=E(!1),b=()=>{d.current?.click()},h=()=>t(n=>!n),w=n=>{const r=n.target.files?.[0];if(!r)return;const l=new FileReader;l.onload=a=>{const y=a.target?.result;g(y,r.name)},l.onerror=a=>{console.error("Failed to read file!",a)},l.readAsText(r),n.target.value=""};return e.createElement(D,null,e.createElement(I,null,e.createElement("input",{type:"checkbox",checked:m,onChange:n=>f(n.target.checked),id:"hide-warnings"}),"Hide warnings"),e.createElement(F,null,e.createElement(i,{variant:"text",icon:e.createElement(p,{style:{transform:"rotate(180deg)"}}),onClick:b,"aria-label":"Upload spec"}),e.createElement(A,{type:"file",ref:d,onChange:w,accept:".yaml,.yml,.json"}),e.createElement(R,null,e.createElement(i,{onClick:c,iconPosition:"left",icon:e.createElement(p,null)},"Download"),e.createElement(i,{icon:e.createElement(k,null),onClick:h,"aria-label":"Download options"}),x&&e.createElement(z,null,e.createElement(s,{onClick:()=>{c(),t(!1)}},"Download YAML"),e.createElement(s,{onClick:()=>{u(),t(!1)}},"Download JSON")))))}const D=o.div`
|
|
2
|
+
padding: 6px 12px;
|
|
3
|
+
border-bottom: 1px solid var(--border-color-primary);
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
background-color: var(--bg-color);
|
|
7
|
+
color: var(--text-color-primary);
|
|
8
|
+
gap: 16px;
|
|
9
|
+
`,I=o.label`
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
gap: 8px;
|
|
13
|
+
font-size: 0.875rem;
|
|
14
|
+
cursor: pointer;
|
|
15
|
+
`,F=o.div`
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
gap: 8px;
|
|
19
|
+
margin-left: auto; /* Push to far right */
|
|
20
|
+
`,R=o.div`
|
|
21
|
+
position: relative;
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: row;
|
|
26
|
+
gap: calc(var(--spacing-xxs) / 2);
|
|
27
|
+
`,z=o.ul`
|
|
28
|
+
position: absolute;
|
|
29
|
+
right: 0;
|
|
30
|
+
top: 100%;
|
|
31
|
+
margin: 4px 0 0 0;
|
|
32
|
+
padding: 4px 0;
|
|
33
|
+
list-style: none;
|
|
34
|
+
border: 1px solid var(--border-color-primary, #ccc);
|
|
35
|
+
background-color: var(--bg-color, #fff);
|
|
36
|
+
color: var(--text-color-primary, #111);
|
|
37
|
+
border-radius: 4px;
|
|
38
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
39
|
+
min-width: 140px;
|
|
40
|
+
z-index: 20;
|
|
41
|
+
`,s=o.li`
|
|
42
|
+
padding: 6px 12px;
|
|
43
|
+
font-size: 0.875rem;
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
&:hover {
|
|
46
|
+
background-color: var(--bg-color-active, #f5f5f5);
|
|
47
|
+
}
|
|
48
|
+
`,A=o.input`
|
|
49
|
+
display: none;
|
|
50
|
+
`;export{C as default};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
|
+
export declare const DEFAULT_EDITOR_OPTIONS: Monaco.editor.IStandaloneEditorConstructionOptions;
|
|
3
|
+
export declare const EDITOR_LANGUAGE = "yaml";
|
|
4
|
+
export declare const EDITOR_THEMES: {
|
|
5
|
+
readonly light: "light";
|
|
6
|
+
readonly dark: "vs-dark";
|
|
7
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t={padding:{top:12,bottom:12},fontSize:14,tabSize:2,detectIndentation:!0,minimap:{enabled:!1},renderLineHighlight:"all",placeholder:"Drag your file here or start typing...",stickyScroll:{enabled:!0}},e="yaml",r={light:"light",dark:"vs-dark"};export{t as DEFAULT_EDITOR_OPTIONS,e as EDITOR_LANGUAGE,r as EDITOR_THEMES};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import t from"./components/Page";const e={seo:{title:"Redocly Editor"},slug:"/editor"};var r=t;export{r as default,e as frontmatter};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useColorMode: () => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useEffect as r,useState as s}from"react";const d=()=>{const[t,o]=s(typeof document<"u"&&document.documentElement.classList.contains("dark")?"dark":"light");return r(()=>{if(typeof document>"u")return;const e=new MutationObserver(()=>{const n=document.documentElement.classList.contains("dark");o(n?"dark":"light")});return e.observe(document.documentElement,{attributes:!0,attributeFilter:["class"]}),()=>{e.disconnect()}},[]),t};export{d as useColorMode};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { editor } from 'monaco-editor';
|
|
2
|
+
export interface EditorState {
|
|
3
|
+
value: string;
|
|
4
|
+
setValue: (value: string) => void;
|
|
5
|
+
validatedValue: string | undefined;
|
|
6
|
+
setValidatedValue: (value: string | undefined) => void;
|
|
7
|
+
validationErrors: editor.IMarkerData[];
|
|
8
|
+
setValidationErrors: (errors: editor.IMarkerData[]) => void;
|
|
9
|
+
fileName: string;
|
|
10
|
+
setFileName: (fileName: string) => void;
|
|
11
|
+
parsedErrors: (editor.IMarkerData & {
|
|
12
|
+
rule: string;
|
|
13
|
+
})[];
|
|
14
|
+
hasStructErrors: boolean;
|
|
15
|
+
hideWarnings: boolean;
|
|
16
|
+
setHideWarnings: (hide: boolean) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare function useEditorState(): EditorState;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useEffect as l,useMemo as n,useState as t}from"react";function h(){const i=typeof localStorage<"u"&&localStorage.getItem("editorValue")||"",[e,u]=t(i),[c,o]=t(void 0),[r,d]=t([]),[m,f]=t(""),[V,g]=t(!1),E=/Rule: ([\w-_\/]+)/,s=n(()=>r.map(a=>({...a,rule:a.message.match(E)?.[1]})),[r]),S=n(()=>s.some(a=>a.rule==="struct"),[s]);return l(()=>{localStorage.setItem("editorValue",e)},[e]),l(()=>{o(e)},[e]),{value:e,setValue:u,validatedValue:c,setValidatedValue:o,validationErrors:r,setValidationErrors:d,fileName:m,setFileName:f,hideWarnings:V,setHideWarnings:g,parsedErrors:s,hasStructErrors:S}}export{h as useEditorState};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface FileOperationsCallbacks {
|
|
2
|
+
setValue: (value: string) => void;
|
|
3
|
+
setFileName: (name: string) => void;
|
|
4
|
+
setHasRenderedOnce: (hasRendered: boolean) => void;
|
|
5
|
+
setValidationErrors: (errors: any[]) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function useFileOperations(callbacks: FileOperationsCallbacks): {
|
|
8
|
+
handleFileLoad: (content: string, fileName: string) => void;
|
|
9
|
+
handleTemplateClick: () => void;
|
|
10
|
+
handleDownloadYaml: (value: string) => void;
|
|
11
|
+
handleDownloadJson: (value: string) => void;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{dump as p,load as e}from"js-yaml";import{downloadFile as d}from"../utils/download";import{defaultOpenapiTemplate as m}from"../templates/defaultOpenapiTemplate";function L(s){const{setValue:a,setFileName:i,setHasRenderedOnce:r,setValidationErrors:l}=s;return{handleFileLoad:(n,o)=>{a(n),console.log(`Loaded file: ${o}`),i(o),r(!1),l([])},handleTemplateClick:()=>{a(m),console.log("Loaded default template."),r(!1),l([])},handleDownloadYaml:n=>{let o=n;try{if(n.trim().startsWith("{")){const t=JSON.parse(n);o=p(t)}else e(n),o=n}catch(t){try{e(n),o=n}catch(c){alert("Content is not valid JSON or YAML. Cannot convert to YAML for download."),console.error("Error preparing YAML for download:",t,c);return}}d(o,"openapi.yaml","application/x-yaml")},handleDownloadJson:n=>{try{const o=e(n);if(typeof o!="object"||o===null)throw new Error("Parsed content is not an object.");const t=JSON.stringify(o,null,2);d(t,"openapi.json","application/json")}catch(o){alert("Content is not valid YAML/JSON. Cannot convert to JSON for download."),console.error("Error preparing JSON for download:",o)}}}}export{L as useFileOperations};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { editor, Position } from "monaco-editor";
|
|
2
|
+
export interface MonacoEditorOptions {
|
|
3
|
+
onValidationUpdate?: (errors: editor.IMarkerData[], value: string) => void;
|
|
4
|
+
onClick?: (position: Position) => void;
|
|
5
|
+
hideWarnings?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function useMonacoEditor({ onValidationUpdate, onClick, hideWarnings }: MonacoEditorOptions): {
|
|
8
|
+
editorRef: import("react").MutableRefObject<editor.IStandaloneCodeEditor | null>;
|
|
9
|
+
monacoRef: import("react").MutableRefObject<null>;
|
|
10
|
+
activeColorMode: string;
|
|
11
|
+
handleEditorDidMount: (editor: editor.IStandaloneCodeEditor, monaco: any) => () => void;
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useEffect as M,useRef as r}from"react";import{LanguageServerService as d}from"../services/languageServerService";import{useColorMode as v}from"./useColorMode";import{useThemeHooks as D}from"@redocly/theme/core/hooks";function w({onValidationUpdate:n,onClick:i,hideWarnings:e}){const u=r(null),c=r(null),o=r(null),{useGlobalData:s}=D(),R=s(),a=v(),f=(t,l)=>{u.current=t,c.current=l,o.current||(o.current=new d),o.current.initialize(t,l);const m=o.current.setupAutoValidation(n,e);return t.onMouseDown(({target:p})=>{i?.(p.position)}),()=>{m()}};return M(()=>{o.current?.setupAutoValidation(n,e)},[e]),{editorRef:u,monacoRef:c,activeColorMode:a,handleEditorDidMount:f}}export{w as useMonacoEditor};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface OpenApiValidationHook {
|
|
2
|
+
definition: any | null;
|
|
3
|
+
hasRenderedOnce: boolean;
|
|
4
|
+
setHasRenderedOnce: (hasRendered: boolean) => void;
|
|
5
|
+
}
|
|
6
|
+
interface ValidationDependencies {
|
|
7
|
+
validatedValue: string | undefined;
|
|
8
|
+
hasStructErrors: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Custom hook to handle OpenAPI definition validation and parsing
|
|
12
|
+
*/
|
|
13
|
+
export declare function useOpenApiValidation({ validatedValue, hasStructErrors }: ValidationDependencies): OpenApiValidationHook;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useState as s,useEffect as p}from"react";import{load as c}from"js-yaml";function O({validatedValue:t,hasStructErrors:o}){const[f,n]=s(null),[i,r]=s(!1);return p(()=>{try{if(o){n(null);return}if(!t){n(null);return}const e=c(t);if(!(e&&typeof e=="object"&&e.openapi&&typeof e.openapi=="string")){n(null);return}n(e),i||r(!0)}catch{n(null)}},[t,o,i]),{definition:f,hasRenderedOnce:i,setHasRenderedOnce:r}}export{O as useOpenApiValidation};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type * as Monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|
2
|
+
export interface LSPosition {
|
|
3
|
+
line: number;
|
|
4
|
+
character: number;
|
|
5
|
+
}
|
|
6
|
+
export interface DocumentProvider {
|
|
7
|
+
getText: (options?: {
|
|
8
|
+
start?: number;
|
|
9
|
+
end?: number;
|
|
10
|
+
}) => string;
|
|
11
|
+
offsetAt: (position: LSPosition) => number;
|
|
12
|
+
positionAt: (offset: number) => Monaco.IPosition;
|
|
13
|
+
}
|
|
14
|
+
export interface ValidationCallback {
|
|
15
|
+
(errors: Monaco.editor.IMarkerData[], value: string): void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Service class to handle OpenAPI Language Server integration
|
|
19
|
+
*/
|
|
20
|
+
export declare class LanguageServerService {
|
|
21
|
+
private monaco;
|
|
22
|
+
private editor;
|
|
23
|
+
constructor();
|
|
24
|
+
/**
|
|
25
|
+
* Initialize the language server with Monaco editor instance
|
|
26
|
+
*/
|
|
27
|
+
initialize(editor: Monaco.editor.IStandaloneCodeEditor, monaco: typeof Monaco): void;
|
|
28
|
+
/**
|
|
29
|
+
* Register documents provider for the language server
|
|
30
|
+
*/
|
|
31
|
+
private registerDocumentsProvider;
|
|
32
|
+
/**
|
|
33
|
+
* Create document provider for current editor content
|
|
34
|
+
*/
|
|
35
|
+
private createDocumentProvider;
|
|
36
|
+
/**
|
|
37
|
+
* Register completion item provider
|
|
38
|
+
*/
|
|
39
|
+
private registerCompletionProvider;
|
|
40
|
+
/**
|
|
41
|
+
* Register definition provider
|
|
42
|
+
*/
|
|
43
|
+
private registerDefinitionProvider;
|
|
44
|
+
/**
|
|
45
|
+
* Validate OpenAPI content and provide diagnostics
|
|
46
|
+
*/
|
|
47
|
+
validateContent(onValidationUpdate?: ValidationCallback, hideWarnings?: boolean): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Setup automatic validation on content changes
|
|
50
|
+
*/
|
|
51
|
+
setupAutoValidation(onValidationUpdate?: ValidationCallback, hideWarnings?: boolean): () => void;
|
|
52
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{load as v}from"js-yaml";class M{constructor(){this.monaco=null,this.editor=null}initialize(n,r){this.editor=n,this.monaco=r}registerDocumentsProvider(){}createDocumentProvider(){return{getText:({start:n=0,end:r=void 0}={})=>(this.editor?.getModel()?.getValue()||"").slice(n,r),offsetAt:n=>{const r=this.editor?.getModel();return r?r.getOffsetAt({lineNumber:n.line+1,column:n.character+1}):0},positionAt:n=>{const r=this.editor?.getModel();if(!r)return{lineNumber:1,column:1};const s=r.getPositionAt(n);return{lineNumber:s.lineNumber,column:s.column}}}}registerCompletionProvider(){this.monaco&&this.monaco.languages.registerCompletionItemProvider("yaml",{triggerCharacters:[" ",`
|
|
2
|
+
`,"\\","/",'"',"'"],provideCompletionItems:async(n,r)=>({suggestions:[]})})}registerDefinitionProvider(){this.monaco&&this.monaco.languages.registerDefinitionProvider("yaml",{provideDefinition:async(n,r)=>[]})}async validateContent(n,r){if(!this.editor||!this.monaco)return;const s=this.editor.getModel();if(!s)return;const o=s.getValue(),C={uri:s.uri.toString(),languageId:"yaml",version:s.getVersionId(),getText:()=>o,positionAt:e=>{const c=s.getPositionAt(e);return{line:c.lineNumber-1,character:c.column-1}},offsetAt:e=>s.getOffsetAt({lineNumber:e.line+1,column:e.character+1}),lineCount:s.getLineCount()};try{let e=[];r&&(e=e.filter(t=>t.severity!==4));let c=null;try{v(o)}catch(t){c={severity:8,message:t.reason+" Rule: struct",startLineNumber:t.mark?.line||1,startColumn:0,endLineNumber:t.mark?.line||1,endColumn:1e3},e.push(c)}const u=o.split(`
|
|
3
|
+
`);u.forEach((t,i)=>{const p=t.match(/^\s*type:\s*([^\s#]+)\s*(?:#.*)?$/);if(p){const l=L(u,i),m=l?new Set(["apiKey","http","oauth2","openIdConnect"]):new Set(["string","number","integer","boolean","array","object"]),a=p[1].trim();if(!m.has(a)){const g=t.indexOf("type:")+5+2;e.push({severity:8,message:l?`Invalid security scheme type '${a}'. Allowed: apiKey, http, oauth2, openIdConnect. Rule: struct`:`Invalid schema type '${a}'. Allowed: string, number, integer, boolean, array, object. Rule: struct`,startLineNumber:i+1,startColumn:Math.max(1,g),endLineNumber:i+1,endColumn:t.length+1,source:"Custom YAML Validator"})}}const f=t.match(/^(\s*)-(\s*)$/);if(f){const l={severity:8,message:"Empty list item detected. List items should have content. Rule: struct",startLineNumber:i+1,startColumn:f[1].length+1,endLineNumber:i+1,endColumn:t.length+1,source:"Custom YAML Validator"};e.push(l)}const d=t.match(/^(\s*)([^#\s][^:]*):\s*$/);if(d&&!t.trim().endsWith(":")){const l=d[2].trim().toLowerCase();if(["version","title","description","type","format","required","default","example"].some(a=>l.includes(a))){const a={severity:8,message:"Key without value detected. This key typically requires a value. Rule: struct",startLineNumber:i+1,startColumn:d[1].length+1,endLineNumber:i+1,endColumn:t.length+1,source:"Custom YAML Validator"};e.push(a)}}const y=t.match(/^(\s*)-(\s*)(.*)$/);if(y){const[l,m,a,g]=y;if(g.trim().length>0&&a.length!==1){const b={severity:8,message:a.length===0?"Missing space after dash in list item. There should be exactly one space between the dash and content. Rule: struct":"Too many spaces after dash in list item. There should be exactly one space between the dash and content. Rule: struct",startLineNumber:i+1,startColumn:m.length+2,endLineNumber:i+1,endColumn:t.length+1,source:"Custom YAML Validator"};e.push(b)}}}),this.monaco.editor.setModelMarkers(s,"openapi-ls",e),n&&n(e,o)}catch(e){console.error("Error during validation:",e)}}setupAutoValidation(n,r){if(!this.editor)return()=>{};const s=()=>this.validateContent(n,r);s();const o=this.editor.onDidChangeModelContent(()=>{s()});return()=>o.dispose()}}function L(h,n){const s=(h[n]||"").match(/^\s*/)?.[0].length||0;for(let o=n;o>=0;o--){const e=(h[o]??"").replace(/#.*$/,"");if(!e.trim())continue;const c=e.match(/^\s*/)?.[0].length||0,u=e.match(/^\s*([A-Za-z0-9_\-]+):\s*$/);if(u&&c<s&&u[1]==="components")return!1;if(u&&c<=s){const t=u[1];if(t==="securitySchemes")return!0;if(new Set(["schemas","responses","parameters","examples","requestBodies","headers","links","callbacks","pathItems"]).has(t))return!1}}return!1}export{M as LanguageServerService};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const defaultOpenapiTemplate = "openapi: 3.0.0\ninfo:\n title: My API\n version: 1.0.0\n description: A new API to be documented.\npaths:\n /example:\n get:\n summary: Example endpoint\n description: This is a sample endpoint.\n responses:\n '200':\n description: Successful response\n content:\n application/json:\n schema:\n type: object\n properties:\n message:\n type: string\n example: Hello World!\n";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const e=`openapi: 3.0.0
|
|
2
|
+
info:
|
|
3
|
+
title: My API
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
description: A new API to be documented.
|
|
6
|
+
paths:
|
|
7
|
+
/example:
|
|
8
|
+
get:
|
|
9
|
+
summary: Example endpoint
|
|
10
|
+
description: This is a sample endpoint.
|
|
11
|
+
responses:
|
|
12
|
+
'200':
|
|
13
|
+
description: Successful response
|
|
14
|
+
content:
|
|
15
|
+
application/json:
|
|
16
|
+
schema:
|
|
17
|
+
type: object
|
|
18
|
+
properties:
|
|
19
|
+
message:
|
|
20
|
+
type: string
|
|
21
|
+
example: Hello World!
|
|
22
|
+
`;export{e as defaultOpenapiTemplate};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const downloadFile: (content: string, fileName: string, contentType: string) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const c=(o,t,d)=>{const e=document.createElement("a"),n=new Blob([o],{type:d});e.href=URL.createObjectURL(n),e.download=t,document.body.appendChild(e),e.click(),document.body.removeChild(e)};export{c as downloadFile};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as t from"react";function g({RedoclyOpenAPIDocs:c}){const[n,r]=t.useState(null),a=t.useRef(null),[h,d]=t.useState("light"),u=t.useRef(!1),p=t.useRef(null);return t.useEffect(()=>{const s=new URLSearchParams(window.location.search).get("theme");if(s)d(s);else{const e=document.documentElement.classList.contains("dark");d(e?"dark":"light")}window.updateDefinition=e=>{if(e&&typeof e=="object"&&typeof e.openapi=="string"){const o=y(e);a.current=o,r(o)}else a.current?p.current!==a.current&&r(a.current):r(null);p.current=e},window.parent.onReady(window)},[]),t.useEffect(()=>{h==="dark"?document.documentElement.classList.add("dark"):document.documentElement.classList.remove("dark")},[h]),t.useEffect(()=>{const f=()=>{if(u.current)return;const e=document.querySelector("article");if(!e)return;const i=window.innerHeight,o=e.scrollHeight,m=window.scrollY,l=o-i;if(l<=0)return;const w=Math.round(m/l*100);window.parent.postMessage({type:"scroll-sync",position:{absolute:m,relative:w},source:"preview"},"*")},s=e=>{if(e.data?.type==="theme-change"){d(e.data.theme);return}if(e.data?.type!=="scroll-sync"||e.data?.source==="preview"||u.current)return;const i=document.querySelector("article");if(!i)return;const o=window.innerHeight,l=i.scrollHeight-o;if(l<=0)return;u.current=!0;const w=Math.round(e.data.position.relative/100*l);window.scrollTo({top:w,behavior:"smooth"}),setTimeout(()=>{u.current=!1},50)};return window.addEventListener("scroll",f),window.addEventListener("message",s),()=>{window.removeEventListener("scroll",f),window.removeEventListener("message",s)}},[]),n?t.createElement(c,{store:{options:{routingBasePath:"/preview",disableRouter:!0,hideSidebar:!0,scrollYOffset:0},definition:n}}):t.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh",fontFamily:"system-ui, -apple-system, sans-serif",color:"#666"}},"No API definition available")}function y(c){try{const n={...c};return Array.isArray(n.servers)&&(n.servers=n.servers.filter(r=>r&&typeof r=="object").filter(r=>typeof r.url=="string"&&r.url.trim().length>0)),n}catch{return c}}export{g as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/marketing-pages",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"keywords": [],
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -23,38 +23,44 @@
|
|
|
23
23
|
"@codemirror/language": "^6.11.0",
|
|
24
24
|
"@codemirror/legacy-modes": "^6.5.1",
|
|
25
25
|
"@itseasy21/react-elastic-carousel": "^0.12.3",
|
|
26
|
+
"@monaco-editor/react": "^4.7.0",
|
|
26
27
|
"@rebilly/lead-source-tracker": "^2.18.13",
|
|
27
28
|
"@redocly/json-to-json-schema": "^0.0.1",
|
|
28
29
|
"@uiw/react-codemirror": "^4.23.12",
|
|
29
30
|
"dayjs": "^1.11.13",
|
|
30
31
|
"framer-motion": "^12.10.5",
|
|
32
|
+
"highlight-words-core": "^1.2.3",
|
|
33
|
+
"html2canvas": "^1.4.1",
|
|
31
34
|
"js-yaml": "^4.1.0",
|
|
35
|
+
"json-schema-to-ts": "^3.1.0",
|
|
36
|
+
"jspdf": "^3.0.2",
|
|
32
37
|
"lottie-react": "^2.4.0",
|
|
38
|
+
"monaco-editor": "^0.53.0",
|
|
33
39
|
"polished": "^4.2.2",
|
|
34
40
|
"react-copy-to-clipboard": "^5.1.0",
|
|
35
41
|
"react-helmet": "^6.1.0",
|
|
36
42
|
"react-hook-form": "^7.56.3",
|
|
37
43
|
"react-hubspot-form": "^1.3.7",
|
|
44
|
+
"react-resizable-panels": "^3.0.6",
|
|
38
45
|
"react-responsive-carousel": "^3.2.23",
|
|
39
|
-
"react-spring": "^9.
|
|
46
|
+
"react-spring": "^9.6.2",
|
|
40
47
|
"react-tabs": "^6.1.0",
|
|
41
48
|
"react-tooltip": "^4.2.21",
|
|
42
49
|
"reactjs-popup": "^2.0.6",
|
|
50
|
+
"styled-system": "^5.1.5",
|
|
43
51
|
"ulid": "^2.3.0",
|
|
44
|
-
"vitest": "^3.1.3"
|
|
45
|
-
"html2canvas": "^1.4.1",
|
|
46
|
-
"jspdf": "^3.0.2",
|
|
47
|
-
"json-schema-to-ts": "^3.1.0"
|
|
52
|
+
"vitest": "^3.1.3"
|
|
48
53
|
},
|
|
49
54
|
"peerDependencies": {
|
|
50
|
-
"react": "^18.3.1",
|
|
51
|
-
"react-dom": "^18.3.1",
|
|
55
|
+
"react": "^18.3.1 || ^19.0.0",
|
|
56
|
+
"react-dom": "^18.3.1 || ^19.0.0",
|
|
52
57
|
"styled-components": ">=5.3.11"
|
|
53
58
|
},
|
|
54
59
|
"devDependencies": {
|
|
55
60
|
"@changesets/cli": "^2.29.5",
|
|
56
61
|
"@redocly/config": "^0.24.0",
|
|
57
62
|
"@redocly/theme": "^0.53.0",
|
|
63
|
+
"@markdoc/markdoc": "0.5.1",
|
|
58
64
|
"@shikijs/types": "3.4.0",
|
|
59
65
|
"@types/js-yaml": "^4.0.9",
|
|
60
66
|
"@types/node": "^22.15.17",
|