-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexample.qmd
192 lines (145 loc) · 5.14 KB
/
example.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
---
title: Qreacto
format: html
filters:
- _extensions/qreacto/qreacto.lua
sidebar: false
navbar: false
---
Run standalone React components in your Quarto project!
## Getting started
Create your component
``` javascript
function MyComponent() {
const [text, setText] = React.useState(['Click me'])
return (
<div onClick={() => setText((previous) => [previous, ...[' and me']])}>
<p>{text.map(value => <span>{value}</span>)} </p>
</div>
);
}
export default MyComponent
```
add it to your markdown file with `{{{< react MyComponent >}}}`
and see the results:
{{< react MyComponent >}}
## Add styles
Create your component, with the styles imported
``` javascript
import './style.css';
function MyStyledComponent() {
const [text, setText] = React.useState([])
return (
<div onClick={() => setText((previous) => [...previous, ' and this one'])}>
<div className='styled-component-container'>
<span className='wrapper-for-other-component'>Click this one</span>
{text.map(value => <span className='wrapper-for-other-component'>{value}</span>)}
</div>
</div>
);
}
export default MyStyledComponent
```
add it to your markdown file with `{{{< react MyStyledComponent >}}}`
and see the results:
{{< react MyStyledComponent >}}
## Import local scripts
Create your component, with the scripts imported
``` javascript
import './style.css';
import getRandomEmoji from './emojiservice'; // we are importing a script here
function EmojiComponent() {
const [text, setText] = React.useState([getRandomEmoji()])
return (
<div onClick={() => setText((previous) => [...previous, getRandomEmoji()])}>
<div className='styled-component-container'>
{text.map(value => <span className='wrapper-for-other-component'>{value}</span>)}
</div>
</div>
);
}
export default EmojiComponent
```
add it to your markdown file with `{{{< react EmojiComponent >}}}`
and see the results:
{{< react EmojiComponent >}}
## Import thirdparty scripts
Create your component, with thirdparty scripts imported.
Any CDN that supports ESM packages can be used, like [jsDelivr](https://www.jsdelivr.com/esm)
``` javascript
import './style.css';
import * as randomWords from 'https://cdn.jsdelivr.net/npm/random-words/+esm'; // we are importing a thirdparty script here
function RandomWordsComponent() {
const [text, setText] = React.useState([randomWords.generate({ maxLength: 8 })])
return (
<div onClick={() => setText((previous) => [...previous, randomWords.generate({ maxLength: 8 })])}>
<div className='styled-component-container'>
{text.map(value => <span className='wrapper-for-other-component'>{value}</span>)}
</div>
</div>
);
}
export default RandomWordsComponent
```
add it to your markdown file with `{{{< react RandomWordsComponent >}}}`
and see the results:
{{< react RandomWordsComponent >}}
## Nesting components
Create your component with the nested components imported and in the jsx
``` javascript
import RandomWordsComponent from "./RandomWordsComponent";
import EmojiComponent from "./EmojiComponent";
function MyNestedComponent() {
return (
<div>
<RandomWordsComponent/>
<EmojiComponent/>
</div>
);
}
export default MyNestedComponent
```
add it to your markdown file with `{{{< react MyNestedComponent >}}}`
and see the results:
{{< react MyNestedComponent >}}
## Using environment variables
Add your environment variables as specified on the [official documentation](https://quarto.org/docs/projects/environment.html)
Qreacto will pick up environment variables that begin with `QREACTO_`
They can then be accessed with `process.env....`'''
{{< react EnvironmentReadingComponent >}}
The enviornment file:
``` bash
QREACTO_FOO=bar
QREACTO_TEST=Very true
```
Results in:
``` json
{
env: {
QREACTO_FOO:"bar"
QREACTO_TEST:"Very true"
}
}
```
and can be accessed with:
``` javascript
console.log(process.env.QREACTO_FOO)
console.log(process.env.QREACTO_TEST)
```
**Note** Qreacto only looks for `_environment` files, not iterations of this file (eg _environment-dev, _environment-prod)
## Configuring
You can (optionally) specify the location for your components and resources
``` yaml
react:
components: _components
resources: _resources
```
## Gotchas
- Dont import react in your file `import React from 'react'`
- components should be placed in the `_components/` folder
- styles and supporting scripts should be placed in the `_components/` folder
- Changes to your component will not refresh quarto, `quarto preview` or `quarto render` will need to be called.
- Typescript is supported but is limited to babels transpilation support of TS. As such, it may not have the latest features you would expect
- Named imports are not currently supported `import { NamedButton } from './Button';` will not work but `import Button from './Button'` will.
- Deep imports are not currently supported. components should be placed in the `_components/` folder.
- Works with `md` and `qmd` other extensions might work but have not been tested.