-
-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: custom extension rendering #994
base: master
Are you sure you want to change the base?
Changes from 29 commits
db17606
a52c230
22f07b3
18654d2
9b978b8
de451e8
13a8a6c
23401a9
6c4f19f
37bc952
3b19209
95bfa86
8492e7a
389e407
973c1da
4b03c14
3b548f5
cae5861
8caea6e
f986398
979777d
a34f50a
32cf262
c630f89
eed70c4
350646a
d91df2a
3e57a3f
1740980
361a2c2
aa7423b
8384cd8
3563ab1
df932da
a25f1d2
ec52216
7ab4925
d4cda82
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,107 @@ | ||
/* eslint-disable @typescript-eslint/no-unsafe-return */ | ||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */ | ||
|
||
import React from 'react'; | ||
import React, { useState } from 'react'; | ||
|
||
import { Schema } from './Schema'; | ||
|
||
import { SchemaHelpers } from '../helpers'; | ||
import { AsyncAPIDocumentInterface, BaseModel } from '@asyncapi/parser'; | ||
import { useConfig, useSpec } from '../contexts'; | ||
import { CollapseButton } from './CollapseButton'; | ||
|
||
interface Props { | ||
name?: string; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
item: any; | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export interface ExtensionComponentProps<V = any> { | ||
propertyName: string; | ||
propertyValue: V; | ||
document: AsyncAPIDocumentInterface; | ||
parent: BaseModel; | ||
} | ||
|
||
export const Extensions: React.FunctionComponent<Props> = ({ | ||
name = 'Extensions', | ||
item, | ||
}) => { | ||
const [expanded, setExpanded] = useState(false); | ||
const [deepExpand, setDeepExpand] = useState(false); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with you. I removed |
||
|
||
const config = useConfig(); | ||
const document = useSpec(); | ||
|
||
const extensions = SchemaHelpers.getCustomExtensions(item); | ||
if (!extensions || !Object.keys(extensions).length) { | ||
return null; | ||
} | ||
|
||
const schema = SchemaHelpers.jsonToSchema(extensions); | ||
if (!config.extensions || !Object.keys(config.extensions).length) { | ||
const schema = SchemaHelpers.jsonToSchema(extensions); | ||
return ( | ||
schema && ( | ||
<div className="mt-2"> | ||
<Schema schemaName={name} schema={schema} onlyTitle={true} /> | ||
</div> | ||
) | ||
); | ||
} | ||
|
||
return ( | ||
schema && ( | ||
<div className="mt-2"> | ||
<Schema schemaName={name} schema={schema} onlyTitle /> | ||
<div> | ||
<div className="flex py-2"> | ||
<div className="min-w-1/4"> | ||
<> | ||
<CollapseButton | ||
onClick={() => setExpanded((prev) => !prev)} | ||
expanded={expanded} | ||
> | ||
<span className={`break-anywhere text-sm ${name}`}>{name}</span> | ||
</CollapseButton> | ||
<button | ||
type="button" | ||
onClick={() => setDeepExpand((prev) => !prev)} | ||
className="ml-1 text-sm text-gray-500" | ||
> | ||
{deepExpand ? 'Collapse all' : 'Expand all'} | ||
</button> | ||
</> | ||
</div> | ||
</div> | ||
<div | ||
className={`rounded p-4 py-2 border bg-gray-100 ${expanded ? 'block' : 'hidden'}`} | ||
> | ||
{Object.keys(extensions) | ||
.sort((extension1, extension2) => | ||
extension1.localeCompare(extension2), | ||
) | ||
.map((extensionKey) => { | ||
if (config.extensions?.[extensionKey]) { | ||
const CustomExtensionComponent = config.extensions[extensionKey]; | ||
return ( | ||
<CustomExtensionComponent | ||
key={extensionKey} | ||
propertyName={extensionKey} | ||
propertyValue={extensions[extensionKey]} | ||
document={document} | ||
parent={item} | ||
/> | ||
); | ||
} else { | ||
const extensionSchema = SchemaHelpers.jsonToSchema( | ||
extensions[extensionKey], | ||
); | ||
return ( | ||
<div key={extensionKey} className="mt-2"> | ||
<Schema schemaName={extensionKey} schema={extensionSchema} /> | ||
</div> | ||
); | ||
} | ||
})} | ||
</div> | ||
) | ||
</div> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import React from 'react'; | ||
import { ExtensionComponentProps } from '../Extensions'; | ||
|
||
/** | ||
* See <https://github.com/asyncapi/extensions-catalog/blob/master/extensions/x.md>. | ||
*/ | ||
export default function XExtension({ | ||
propertyValue, | ||
}: ExtensionComponentProps<string>) { | ||
const onClickHandler = () => { | ||
window.open(`https://x.com/${propertyValue}`, '_blank'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think for best practices we should include the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added the attribute in the anchor tag. |
||
}; | ||
|
||
return ( | ||
<div | ||
title={`https://x.com/${propertyValue}`} | ||
style={{ display: 'inline-block' }} | ||
> | ||
<svg | ||
onClick={onClickHandler} | ||
style={{ cursor: 'pointer' }} | ||
width="15px" | ||
height="15px" | ||
viewBox="0 0 1200 1227" | ||
fill="none" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z" | ||
fill="black" | ||
/> | ||
</svg> | ||
</div> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity why aren't we wrapping it an anchor tag? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for pointing it out. I wasn't paying attention here. |
||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should probably move this to the types file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved it into the types file