Skip to content

Commit 6709e86

Browse files
authored
Merge pull request #108 from revisit-studies/adding-structured-links
Added structured links
2 parents 9d94554 + e850774 commit 6709e86

File tree

5 files changed

+177
-0
lines changed

5 files changed

+177
-0
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,31 @@ Some **content** with _Markdown_ `syntax`. Check [this `api`](#).
5757
* hyphen: - use for hyphenation
5858

5959

60+
**Custom Structured Links Component:**
61+
62+
We can add a "structured links" component to any of our Markdown files like so:
63+
64+
```markdown
65+
import StructuredLinks from '../../src/components/StructuredLinks/StructuredLinks.tsx';
66+
67+
<StructuredLinks
68+
demoLink="https://revisit.dev/study/demo-vega/"
69+
codeLink="https://github.com/revisit-studies/study/tree/main/public/demo-vega"
70+
referenceLinks={
71+
[
72+
{name: "Vega", url:"https://vega.github.io/vega/"},
73+
{name: "Vega-Lite", url: "https://vega.github.io/vega-lite/"},
74+
{name: "Vega Config Component", url: "../../typedoc/interfaces/VegaComponentConfig/"},
75+
{name: "Vega Path Component", url: "../../typedoc/interfaces/VegaComponentPath/"}
76+
]
77+
}
78+
/>
79+
```
80+
81+
The "demoLink" is a static path and will appear as "Live Demo". The "codeLink" is also static and will appear as "Demo Code". The reference links is a list with the associated displayed names (the "name" key) and the associated URL ( the "url" key).
82+
83+
Note that this wil _only_ render when we have the right-hand sidebar in the markdown file which appears when we have separated headers to navigate.
84+
85+
6086

6187

docs/designing-studies/forms.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Designing Forms
22

3+
import StructuredLinks from '../../src/components/StructuredLinks/StructuredLinks.tsx';
4+
5+
<StructuredLinks
6+
demoLink="https://revisit.dev/study/demo-survey/"
7+
codeLink="https://github.com/revisit-studies/study/blob/main/public/demo-survey/config.json"
8+
referenceLinks={[{name: "Form Elements Overview", url:"../../typedoc/#form-elements"}]}
9+
/>
10+
311
Form elements are essential for most studies to capture user responses. reVISit provides rich form elements, such as slides, check-boxes, text fields, etc, so that you can efficiently design your forms.
412

513
This tutorial does not give a comprehensive introduction into all form elements. For this, refer to the demo and the reference, shown below:

docs/designing-studies/vega-stimulus.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Designing a Vega Stimulus
22

3+
import StructuredLinks from '../../src/components/StructuredLinks/StructuredLinks.tsx';
4+
5+
<StructuredLinks
6+
demoLink="https://revisit.dev/study/demo-vega/"
7+
codeLink="https://github.com/revisit-studies/study/tree/main/public/demo-vega"
8+
referenceLinks={
9+
[
10+
{name: "Vega", url:"https://vega.github.io/vega/"},
11+
{name: "Vega-Lite", url: "https://vega.github.io/vega-lite/"},
12+
{name: "Vega Config Component", url: "../../typedoc/interfaces/VegaComponentConfig/"},
13+
{name: "Vega Path Component", url: "../../typedoc/interfaces/VegaComponentPath/"}
14+
]
15+
}
16+
/>
17+
318
[Vega](https://vega.github.io/vega/) and [Vega-Lite](https://vega.github.io/vega-lite/) are popular visualization grammars for creating data visualizations.
419
Vega allows you to define the visual appearance and interactive behavior of a visualization in JSON format and generate web-based views using Canvas or SVG.
520

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import styles from './styles.module.css'
2+
import React, { useEffect, useState } from "react";
3+
import ReactDOM from "react-dom";
4+
import Admonition from '@theme/Admonition';
5+
6+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
7+
import { faGithub } from '@fortawesome/free-brands-svg-icons';
8+
import { faLink, faFileAlt } from '@fortawesome/free-solid-svg-icons';
9+
import BrowserOnly from '@docusaurus/BrowserOnly';
10+
interface ReferenceLink {
11+
name: string,
12+
url: string
13+
}
14+
15+
interface StructuredLinkProps {
16+
demoLink?: string;
17+
codeLink?: string;
18+
referenceLinks?: ReferenceLink[];
19+
}
20+
21+
function StructuredLinkInner({ demoLink, codeLink, referenceLinks }: StructuredLinkProps) {
22+
const [container, setContainer] = useState<HTMLElement | null>(null);
23+
// Use placeholder to find element for correct placement
24+
const [placeholder] = useState(() => document.createElement("div"));
25+
26+
useEffect(() => {
27+
28+
const tocContainer: HTMLElement = document.querySelector(".theme-doc-toc-desktop");
29+
if (tocContainer?.parentElement) {
30+
const parentElement = tocContainer.parentElement;
31+
parentElement.insertBefore(placeholder, parentElement.firstChild);
32+
setContainer(placeholder);
33+
}
34+
35+
// Remove placeholder when unmounting
36+
return () => {
37+
placeholder.remove();
38+
};
39+
}, [placeholder]);
40+
41+
if (!demoLink && !codeLink && !referenceLinks) {
42+
return null;
43+
}
44+
45+
return container
46+
? ReactDOM.createPortal(
47+
<div className={styles.container}>
48+
<Admonition type='note' title='Relevant Links'>
49+
<div className={styles.linkContainer}>
50+
{demoLink ?
51+
<div className={styles.demoContainer}>
52+
<div className={styles.iconContainer}>
53+
<FontAwesomeIcon icon={faLink} />
54+
<a target="_blank" href={demoLink}>Live Demo</a>
55+
</div>
56+
</div>
57+
: null}
58+
{codeLink ?
59+
<div className={styles.codeContainer}>
60+
<div className={styles.iconContainer}>
61+
<FontAwesomeIcon icon={faGithub} />
62+
<a target="_blank" href={codeLink}>Demo Code</a>
63+
</div>
64+
</div>
65+
: null}
66+
{referenceLinks && referenceLinks.length > 0 ?
67+
<div className={styles.referencesContainer}>
68+
<div className={styles.iconContainer}>
69+
<FontAwesomeIcon icon={faFileAlt} />
70+
<div className={styles.referencesTitle}>References</div>
71+
</div>
72+
<div style={{ marginLeft: '23px' }}>
73+
{referenceLinks.map(entry =>
74+
<a target="_blank" href={entry.url}>{entry.name}</a>
75+
)
76+
}
77+
</div>
78+
</div>
79+
: null}
80+
</div>
81+
</Admonition>
82+
</div>,
83+
container
84+
)
85+
: null;
86+
}
87+
88+
// BrowserOnly wrapper for use in docusaurus. Without this, docusaurus will fail to build.
89+
function StructuredLink({ demoLink, codeLink, referenceLinks }: StructuredLinkProps) {
90+
return (
91+
<BrowserOnly>
92+
{() => <StructuredLinkInner demoLink={demoLink} codeLink={codeLink} referenceLinks={referenceLinks} />}
93+
</BrowserOnly>
94+
)
95+
}
96+
97+
export default StructuredLink;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
.container {
2+
margin-bottom: 20px;
3+
}
4+
5+
.linkContainer {
6+
/* border: 1px solid red; */
7+
display: flex;
8+
flex-direction: column;
9+
gap: 20px;
10+
padding-top: 20px;
11+
}
12+
13+
.linkContainer div {
14+
display: flex;
15+
flex-direction: column;
16+
}
17+
18+
.linkContainer div .iconContainer {
19+
display: flex;
20+
flex-direction: row;
21+
gap: 10px;
22+
align-items: center;
23+
}
24+
25+
.referencesTitle {
26+
font-weight: bold;
27+
}
28+
29+
.referencesContainer .iconContainer {
30+
margin-bottom: 10px;
31+
}

0 commit comments

Comments
 (0)