elias-sundqvist23k downloadsWrite and use React (Jsx) components in your notes.
This is a plugin for Obsidian (https://obsidian.md).
It allows you to write and use React components with Jsx inside your Obsidian notes.
It is highly recommended that you also install the Editor Syntax Highlight Plugin when using this plugin.

There are two methods for creating react components.
Put a note anywhere in your vault and give it the property defines-react-components. You can also optionally set a specific namespace (series of words separated by dots), using the react-components-namespace property.
This can either be done in the frontmatter, like so:
---
defines-react-components: true
react-components-namespace: projects.test
---
or (if dataview is installed) using dataview inline properties
defines-react-components:: true
react-components-namespace:: projects.test
Then, in your note, to define a component, write a code block like this
```jsx:component:MyComponent
return <div>Hello {props.name}!</div>
```
This will create a component called MyComponent, located in the projects.test namespace (or in the global namespace if you left the property unspecified).
You can then use the component like this:
```jsx:
<MyComponent name={"World"}/>
```
Or, using inline syntax.
`jsx:<MyComponent name={"World"}/>`
If you are in a note which uses a separate namespace, you can access the component like so:
`jsx:<projects.test.MyComponent name={"World"}/>`
An alternative way of creating components is component notes. This approach treats an entire markdown file as the definition of a single react component. A benefit of this approach is that you can open the note in, for example, visual studio code, to get full syntax highlighting and some code autocompletion.
In order to use component notes, you must first specify a folder for the Jsx functions / react components.

Every note in this directory will be interpreted as the content of a Jsx function (implicitly of the form props=>{your code here})
Every file becomes a function/react component with the same name as the note.
The syntax for writing components is regular Jsx Syntax
The content of your component file is implicitly wrapped in props=>{...}. This means that you don't write the function signature yourself. You do, however, need to include the return keyword in your code.
Other things to keep in mind:
Components can be used like this:
```jsx:
<MyComponent name={"World"}/>
```
Or, using inline syntax.
`jsx:<MyComponent name={"World"}/>`
If you are in a note which uses a separate namespace, you can access the component like so:
`jsx:<projects.test.MyComponent name={"World"}/>`
When using the codeblock syntax, (```jsx:), the code can be multiple lines. The last statement is implicitly returned and rendered.
The react components have access to everything inside the global namespace.
Besides this, the components have access to React, ReactDOM, useState, and useEffect.
This allows you to easily write functional components.
Besides that, you can also access the file context through the hook call useContext(ReactComponentContext);. This can then be used to, for example, access the frontmatter as follows:
```jsx:component:ComponentWithFrontmatter
const ctx = useContext(ReactComponentContext);
var frontmatter = ctx.markdownPostProcessorContext.frontmatter;
return <h1>{frontmatter.title}</h1>
```
Feel free to contribute.
You can create an issue to report a bug, suggest an improvement for this plugin, ask a question, etc.
You can make a pull request to contribute to this plugin development.
Markdown component (See issue #25).console.log calls were used when adding the live preview support. These have now been removed.
```jsx::ComponentName
someText
```
Which is equivalent to
```jsx:
<ComponentName src={`someText`}/>
```
but less cluttered.
Example:

jsx: instead of jsx-. 
react-components-namespace property. See Readme for details.use-as-note-header will be used as a header for all notes in the vault. 
import styled from 'https://cdn.skypack.com/styled-components/'
src prop of the Markdown component previously did not cause the component to rerender. This is now fixed..vault_plugin_dir file containing the path to the plugin in your vault: (e.g. path\to\my\vault\.obsidian\plugins\obsidian-react-components). Then yarn build will automatically copy the compiled files to the correct place. So you only have to reload the plugin in Obsidian to see changes take effect.Add a new setting to disable component refreshing
Make component loading more reliable (Resolves issue #13)
Significantly improve error handling
Add a command to manually refresh components
Obsidian React Components: Refresh React ComponentsReplace isPreviewMode with useIsPreview, which check the current pane of the component instead of the currently active component (Resolves issue #12)
Example:
const isPreview = useIsPreview()
if(isPreview) {
// this only happens if the pane which the component is attached to is in preview mode.
}
Markdown component, which can be used to render makdown.`jsx-<Markdown src={"* This is a bullet"}/>`obsidian to the component scopeuseCallback, useContext, useMemo, useReducer, useRef@lucasew Added an isPreviewMode function to the component scope. (PR #5)
There is a rule that in React you must call the same hooks at every render so early returns are not good.
The user can easily check if the note is on preview mode inside its component and can return null if it's the case.
Components which contain sub-components are now correctly updated when the sub-component code is modified. (PR #11)
Users are now warned when creating components with invalid names (PR #10)
// file: Counter.md
const [count, setCount] = useState(0)
return (
<div>
<p>You clicked me {count} times!!!</p>
<button onClick={() => setCount(count + 1)}>
{props.source}
</button>
</div>
)
// file: Clock.md
const [date, setDate] = useState(new Date());
useEffect(() => {
var timerID = setInterval( () => setDate(new Date()), 1000 );
return function cleanup() {
clearInterval(timerID);
};
});
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {date.toLocaleTimeString()}.</h2>
</div>
);
// file: rand.md
return Math.random()
// file: DiceRoller.md
let diceRoll = ()=>Math.ceil(rand()*props.sides)
let [num, setNum] = useState(diceRoll())
return (<span>
<button onClick={()=>setNum(diceRoll())}> Roll the {props.sides}-sided Die</button>
<span>The number is {num}</span>
</span>)
// file: Testcomponent.md
return (
<div style={{color: "blue"}}>
<Clock/>
<Counter source={props.source}/>
</div>
)
Obsidian React Components is licensed under the GNU AGPLv3 license. Refer to LICENSE for more information.