Benjamin-Dobell / react-native-markdown-view

MarkdownView for React Native
MIT License
190 stars 77 forks source link

Preserving applicable styles for rule-affected components #27

Open jiku opened 6 years ago

jiku commented 6 years ago

Is there any preferred approach to preserve passed/default styles for matches when going through a rule?

In a rule for headings, I have

render: (node, output, state, styles) =>
  <Text {...state} style={%S}>
    { node.text.toLowerCase() }
  </Text>

where %S would be any of styles, {styles}, [styles], {[styles]}, {...styles}, [...styles].

These all render unstyled <Text> elements, with the correct amount of leading pound signs, like ### (so the rule works). Each <Text>'s style is an object with all (passed and default) styles keyed by element, like

{
  heading: [...],
  heading1: [...],
  // ...
  heading6: [...],
  // ...
  mailTo: {...},
}

where something like const unkeyedStyles = Object.keys(styles).map((key) => styles[key]) for %S just applies all of them. Here's my current workaround

  render: (node, output, state, styles) => {
  const heading = node.text.split('# ')
  return <Text {...state} style={[styles.text, ...styles.heading, styles[`heading${heading[0].length + 1}`]]}> 
      { heading[1].toLowerCase() }
    </Text>
  }

Is all and not just applicable styles being passed to render a feature or a bug? If it's a feature, is there anything built in that would help with cases like this?

Benjamin-Dobell commented 6 years ago

If I'm understanding you correctly, I think you're just wanting access to the heading "level". The existing heading render function looks like:

heading: (node: HeadingNode, output: OutputFunction, state: RenderState, styles: RenderStyles) => (
    textContentRenderer('heading', 'heading' + node.level)(node, output, state, styles)
),

Note that node is of type HeadingNode, which includes a level property. You ought to be able to use it instead of your string splitting approach.

jiku commented 6 years ago

Oh. node in the React Native debugger only yields

{
  "text": "#  ...",
  "type": "headings"
}

here (typeof(node) === Object, Symbol(node) === Symbol([object Object]), node instanceof Object === true). Maybe type properties aren't carried over from my project not using Flow? If that's it, I can revisit with a PR later if you want. Only passing applicable styles to render, adding a distribution where Flow types are transpiled, or doing something else. Thanks!