Not sure where on the internet to ask this, so I figured I would start where it's trying to be done and see of anybody here has any ideas or resources to lead me towards. I'm desiring to make react components that can be used in mdx documents where I can feed them content like the following, which is sort of a simple YAML like syntax.
<PracticeSchedule>
Week 1:
Day 1:
Play all 12 notes, starting with the note C
Day 2:
Play all 12 notes, starting with the note G
Day 3:
Play all 12 notes, starting with the note D
Day 4:
Play all 12 notes, starting with the note A
Day 5:
Play all 12 notes, starting with the note E
Day 6:
Play all 12 notes, starting with the note B
Day 7:
Rest
Week 2:
Day 1:
Play all 12 notes, starting with the note F#/Gb
Day 2:
Play all 12 notes, starting with the note C#/Db
Day 3:
Play all 12 notes, starting with the note G#/Ab
Day 4:
Play all 12 notes, starting with the note D#/Eb
Day 5:
Play all 12notes, starting with the note A#/Bb
Day 6:
Play all 12 notes, starting with the note F
Day 7:
Rest
</PracticeSchedule>
The preceding would be the desired author experience for a react component I'm working on that is a practice schedule for piano. I originally made a version of this in vanilla HTML and CSS and I tried tables and lists then but they didn't quite work for me in the styling department for various reasons, so I ended up making a series of divs with custom styling that ended up doing the job, but was all hand coded. So I desire to turn all that mess into a react component and feed it data in the preceeding manner, or something similar, that is keeping with the spirit of Markdown/YAML/MDX. I suppose I could feed the components props of arrays and objects filled with strings, but I would like to be able to keep the simple YAML/Markdown feel, even inside an instance of a react component. Does anybody know if something like this is even possible to do, and if so, would it be too much time/effort/trouble to implement?
This isn't very easy to achieve right now since MDX doesn't support embedding MD syntax inside JSX blocks. However, you can achieve something similar by breaking out the PracticeSchedule content into its own file:
index.mdx
import Content from './some-content.mdx'
# Hello, world!
<Content />
some-content.mdx
import styled from 'styled-components'
export default styled.div`
& ul {
color: tomato;
}
& ul ul {
color: rebeccapurple;
}
`
- Item one
- Item one a
- Item one b
- Item two
- Item two a
- Item two b
Then, in some-content.mdx you could import PracticeSchedule and export it as the default.
You could also manipulate the children passed to PracticeSchedule since it will just be a string, but the newline information for your syntax will be lost because JSX, similarly to HTML (or at least most tags/elements), isn't whitespace sensitive.
if you go the child manipulation route, you could also use something likejsYaml in the react component itself to parse children from a string. It'd require the `` syntax for strings though.
<PracticeSchedule>{`
Week 1:
Day 1:
}`</PracticeSchedule>
jsYaml looks interesting...gonna try and get a basic version of the component working first, then will circle back around to this if it seems worth trying...thank you both! 馃榿
So here is how I am structuring my nested lists of content:
<PracticeSchedule
schedule = {
{
Week1: {
Day1: {
Day: `Day 1`,
Tasks: [`1`, `2`, `3`]
},
Day2: {
Day: `Day 2`,
Tasks: [`4`, `5`, `6`]
},
Day3: {
Day: `Day 3`,
Tasks: [`7`, `8`, `9`]
}
},
Week2: {
Day1: {
Day: `Day 1`,
Tasks: [`Uno`, `Does`, `Tres`]
},
Day2: {
Day: `Day 2`,
Tasks: [`Quatro`, `Cinco`, `Seis`]
},
Day3: {
Day: `Day 3`,
Tasks: [`Siete`, `Ocho`, `Nueve`]
}
},
}
}
/>
...and it logs fine in the console, but then I get this error message from react:
Objects are not valid as a React child (found: object with keys {Week1, Week2}). If you meant to render a collection of children, use an array instead.
in h1 (created by PracticeSchedule)
in PracticeSchedule (created by Component)
in div (created by MDXTag)
in MDXTag (created by Context.Consumer)
in Component (created by Component)
in Component (created by Component)
in Component (created by Context.Consumer)
in Component (created by Context.Consumer)
in Component (created by _default)
in div (created by Context.Consumer)
in StyledComponent (created by article__Content)
in article__Content (created by _default)
in div (created by Context.Consumer)
in StyledComponent (created by article__Article)
in article__Article (created by _default)
in MDXProvider (created by _default)
in _default (created by HotExported_default)
in AppContainer (created by HotExported_default)
in HotExported_default (created by PageRenderer)
in main (created by Context.Consumer)
in StyledComponent (created by Main___default)
in Main___default (created by Context.Consumer)
in div (created by Context.Consumer)
in StyledComponent (created by App___default)
in App___default (created by Context.Consumer)
in div (created by Div100vh)
in Div100vh (created by Context.Consumer)
in StaticQuery (created by Layout)
in Layout (created by PageRenderer)
in PageRenderer (created by JSONStore)
in JSONStore (created by EnsureResources)
in ScrollContext (created by EnsureResources)
in RouteUpdates (created by EnsureResources)
in EnsureResources (created by RouteHandler)
in RouteHandler (created by Root)
in div (created by FocusHandlerImpl)
in FocusHandlerImpl (created by Context.Consumer)
in FocusHandler (created by RouterImpl)
in RouterImpl (created by LocationProvider)
in LocationProvider (created by Context.Consumer)
in Location (created by Context.Consumer)
in Router (created by Root)
in Root
in MDXScopeProvider
in _default
with a code highlight:
(anonymous function)
/Users/rchrdnsh/Dropbox/Code/Gatsby/rykr-app/.cache/app.js:56
53 | const preferDefault = m => (m && m.default) || m
54 | let Root = preferDefault(require(`./root`))
55 | domReady(() => {
> 56 | renderer(<Root />, rootElement, () => {
57 | postInitialRenderWork()
58 | apiRunner(`onInitialClientRender`)
59 | })
sooo, not sure what to do...should I just wrap the whole thing in an array? How would I do that? Not sure how that would work, to be honest. Could I simplify my data model as well? Would that be a wise idea...ano how I really do want to get markdown/yaml up in these react components XD
Can you create a CodeSandbox with a reproduction? Sounds like your passing the object directly as children in PracticeSchedule.
This is all I'm doing in the component thus far...
import React from 'react'
const PracticeSchedule = (props) => {
console.log(props.schedule)
return (
<h1>{props.schedule}</h1>
)
}
export default PracticeSchedule;
trying to figure out how to make a code sandbox as well...
https://codesandbox.io/s/github/rchrdnsh/rykr
...will need to open up the render in a new window, cuz mobile styles aren't there yet, tho...
Most helpful comment
This isn't very easy to achieve right now since MDX doesn't support embedding MD syntax inside JSX blocks. However, you can achieve something similar by breaking out the PracticeSchedule content into its own file:
index.mdxsome-content.mdxThen, in
some-content.mdxyou could importPracticeScheduleand export it as the default.You could also manipulate the children passed to
PracticeSchedulesince it will just be a string, but the newline information for your syntax will be lost because JSX, similarly to HTML (or at least most tags/elements), isn't whitespace sensitive.