react-icons/fa#FaMarkdown TypeScript Examples
The following examples show how to use
react-icons/fa#FaMarkdown.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Modal.tsx From hub with Apache License 2.0 | 4 votes |
ChangelogModal = (props: Props) => {
const history = useHistory();
const btnsWrapper = useRef<HTMLDivElement>(null);
const [openStatus, setOpenStatus] = useState<boolean>(false);
const [changelog, setChangelog] = useState<ChangeLog[] | null | undefined>();
const [isLoading, setIsLoading] = useState<boolean>(false);
const [currentPkgId, setCurrentPkgId] = useState<string | undefined>(undefined);
const [activeVersionIndex, setActiveVersionIndex] = useState<number | undefined>(undefined);
const [isGettingMd, setIsGettingMd] = useState<boolean>(false);
const updateVersionInQueryString = (version?: string, index?: number) => {
if (!isUndefined(index)) {
updateActiveVersion(index);
}
history.replace({
search: `?modal=changelog${version ? `&version=${version}` : ''}`,
state: { searchUrlReferer: props.searchUrlReferer, fromStarredPage: props.fromStarredPage },
});
};
useEffect(() => {
setActiveVersionIndex(undefined);
if (props.visibleChangelog && !isUndefined(currentPkgId)) {
getChangelog();
} else if (openStatus && !props.visibleChangelog) {
onCloseModal(false);
}
}, [props.packageId, props.currentVersion]); /* eslint-disable-line react-hooks/exhaustive-deps */
useEffect(() => {
if (props.visibleChangelog && !openStatus && isUndefined(currentPkgId)) {
onOpenModal();
}
}, []); /* eslint-disable-line react-hooks/exhaustive-deps */
useEffect(() => {
if (btnsWrapper && btnsWrapper.current && !isUndefined(activeVersionIndex)) {
const activeChild = btnsWrapper.current.children[activeVersionIndex];
if (!isUndefined(activeChild)) {
// Scroll to active button
activeChild.scrollIntoView({ block: 'nearest' });
}
}
}, [activeVersionIndex]); /* eslint-disable-line react-hooks/exhaustive-deps */
useEffect(() => {
// We load correct active version after rendering modal
if (openStatus && changelog && isUndefined(activeVersionIndex)) {
const version = props.visibleVersion || props.currentVersion;
if (version) {
const currentIndex = changelog.findIndex((ch: ChangeLog) => ch.version === version);
if (currentIndex >= 0) {
if (version === props.currentVersion) {
updateVersionInQueryString(version, currentIndex);
} else {
updateActiveVersion(currentIndex);
}
} else {
updateVersionInQueryString();
setActiveVersionIndex(0);
}
// If version doesn't exist
} else {
updateVersionInQueryString();
setActiveVersionIndex(0);
}
}
}, [openStatus, changelog]); /* eslint-disable-line react-hooks/exhaustive-deps */
if (
[RepositoryKind.Falco, RepositoryKind.Krew, RepositoryKind.HelmPlugin, RepositoryKind.Container].includes(
props.repository.kind
)
)
return null;
async function getChangelog() {
try {
setIsLoading(true);
setCurrentPkgId(props.packageId);
setChangelog(await API.getChangelog(props.packageId));
setIsLoading(false);
setOpenStatus(true);
} catch {
setChangelog(null);
alertDispatcher.postAlert({
type: 'danger',
message: 'An error occurred getting package changelog, please try again later.',
});
setIsLoading(false);
}
}
const onOpenModal = () => {
if (props.hasChangelog) {
getChangelog();
} else {
history.replace({
search: '',
state: { searchUrlReferer: props.searchUrlReferer, fromStarredPage: props.fromStarredPage },
});
}
};
const onCloseModal = (replaceUrl: boolean) => {
setOpenStatus(false);
setActiveVersionIndex(undefined);
setIsGettingMd(false);
setIsLoading(false);
setChangelog(undefined);
if (replaceUrl) {
history.replace({
search: '',
state: { searchUrlReferer: props.searchUrlReferer, fromStarredPage: props.fromStarredPage },
});
}
};
const updateActiveVersion = (versionIndex: number) => {
if (versionIndex !== activeVersionIndex) {
const element = document.getElementById(`changelog-${versionIndex}`);
if (element) {
element.scrollIntoView({ block: 'start' });
}
setActiveVersionIndex(versionIndex);
}
};
const getChangelogMarkdown = () => {
async function getChangelogMd() {
try {
setIsGettingMd(true);
const markdown = await API.getChangelogMD({
packageName: props.normalizedName,
repositoryKind: getRepoKindName(props.repository.kind)!,
repositoryName: props.repository.name,
});
const blob = new Blob([markdown], {
type: 'text/markdown',
});
const link: HTMLAnchorElement = document.createElement('a');
link.download = 'changelog.md';
link.href = window.URL.createObjectURL(blob);
link.style.display = 'none';
document.body.appendChild(link);
link.click();
setIsGettingMd(false);
} catch {
alertDispatcher.postAlert({
type: 'danger',
message: 'An error occurred getting package changelog markdown, please try again later.',
});
setIsGettingMd(false);
}
}
getChangelogMd();
};
return (
<>
<ElementWithTooltip
element={
<button
className={classnames('btn btn-outline-secondary btn-sm text-nowrap w-100', {
disabled: !props.hasChangelog,
})}
onClick={onOpenModal}
aria-label="Open Changelog modal"
aria-disabled={!props.hasChangelog}
>
<div className="d-flex flex-row align-items-center justify-content-center text-uppercase">
{isLoading ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="d-none d-md-inline ms-2 fw-bold">Getting changelog...</span>
</>
) : (
<>
<CgFileDocument />
<span className="ms-2 fw-bold">Changelog</span>
</>
)}
</div>
</button>
}
visibleTooltip={!props.hasChangelog}
tooltipWidth={230}
tooltipClassName={styles.tooltip}
tooltipMessage="No versions of this package include an annotation with information about the changes it introduces."
active
/>
{openStatus && changelog && (
<Modal
modalDialogClassName={styles.modalDialog}
modalClassName="h-100"
header={<div className={`h3 m-2 flex-grow-1 ${styles.title}`}>Changelog</div>}
onClose={() => onCloseModal(true)}
open={openStatus}
closeButton={
<div className="w-100 d-flex flex-row align-items-center justify-content-between">
<button
className="btn btn-sm btn-outline-secondary"
onClick={getChangelogMarkdown}
disabled={isGettingMd}
aria-label="Get changelog markdown"
>
<div className="d-flex flex-row align-items-center">
{isGettingMd ? (
<>
<span className="spinner-grow spinner-grow-sm" role="status" aria-hidden="true" />
<span className="ms-2">Getting markdown</span>
</>
) : (
<>
<FaMarkdown className="me-2" />
<div className="text-uppercase">Get markdown</div>
</>
)}
</div>
</button>
<button
className="btn btn-sm btn-outline-secondary text-uppercase"
onClick={() => onCloseModal(true)}
aria-label="Close modal"
>
<div className="d-flex flex-row align-items-center">
<MdClose className="me-2" />
<div>Close</div>
</div>
</button>
</div>
}
>
<div className="mw-100 h-100">
<div className="d-flex flex-row h-100">
<div className="h-100 d-none d-lg-flex">
<div
className={`d-flex flex-column me-4 border-end overflow-auto ${styles.versionsIndexWrapper}`}
ref={btnsWrapper}
>
{changelog.map((item: ChangeLog, index: number) => {
if (isNull(item.changes) || isUndefined(item.changes)) return null;
return (
<div
data-testid="versionBtnWrapper"
className={classnames(
'pe-4 ps-2 position-relative border-bottom',
styles.versionBtnWrapper,
{
[styles.activeVersionBtnWrapper]: index === activeVersionIndex,
},
{
'border-top': index === 0,
}
)}
key={`opt_${item.version}`}
>
<button
className={classnames(
'btn btn-link text-dark text-start p-0 text-truncate position-relative w-100 rounded-0',
styles.versionBtn
)}
onClick={() => updateActiveVersion(index)}
>
{item.version}
<br />
<small className={`text-muted ${styles.legend}`}>
{moment.unix(item.ts).format('D MMM, YYYY')}
</small>
</button>
</div>
);
})}
</div>
</div>
<Content
changelog={changelog}
onCloseModal={onCloseModal}
updateVersionInQueryString={updateVersionInQueryString}
normalizedName={props.normalizedName}
activeVersionIndex={activeVersionIndex || 0}
setActiveVersionIndex={setActiveVersionIndex}
repository={props.repository}
searchUrlReferer={props.searchUrlReferer}
fromStarredPage={props.fromStarredPage}
/>
</div>
</div>
</Modal>
)}
</>
);
}