mdx-js / mdx

Markdown for the component era
https://mdxjs.com
MIT License
17.71k stars 1.14k forks source link

Table styling and alignment is wonky #930

Closed Everspace closed 4 years ago

Everspace commented 4 years ago

Subject of the issue

When you specify the alignment of a table in markdown syntax, the generated html is strange. It doesn't respect the specified alignment, nor correctly get assigned style.

Your environment

Env

Steps to reproduce

Using the Gatsby starter, place or replace the following mdx in src/pages/index.mdx

| Left | Centre | Right |
|:-----|:------:|------:|
| 1 | 2 | 3 |

navigate to localhost:8000/

Expected behaviour

Every component of the table should receive a style if nessisary, and alignment should be respected based on stated alignment.

<table class="css-somehash">
  <thead class="css-somehash">
    <tr class="css-somehash">
      <th align="left"   class="css-somehash">Left</th>
      <th align="center" class="css-somehash">Centre</th>
      <th align="right"  class="css-somehash">Right</th>
    </tr>
  </thead>
  <tbody class="css-somehash">
    <tr class="css-somehash">
      <td align="left"   class="css-somehash">1</td>
      <td align="center" class="css-somehash">2</td>
      <td align="right"  class="css-somehash">3</td>
    </tr>
  </tbody>
</table>

Actual behaviour

In versions prior to 1.5.5, the alignment was correct, but the css classes were absent on inner tags like tr and th,

<table class="css-0">
  <thead>
    <tr class="css-0">
      <th class="css-0">Left</th>
      <th class="css-0">Centre</th>
      <th class="css-0">right</th>
    </tr>
  </thead>
  <tbody>
    <tr class="css-0">
      <td class="css-0">1</td>
      <td class="css-0">2</td>
      <td class="css-0">3</td>
    </tr>
  </tbody>
</table>
ChristianMurphy commented 4 years ago

@Everspace testing this on the playground with version 1.5.5 I'm not seeing this https://mdxjs.com/playground

the markdown:

| Left | Centre | Right |
|:-----|:------:|------:|
| 1 | 2 | 3 |

produces

/* @jsx mdx */
const makeShortcode = name => function MDXDefaultShortcode(props) {
  console.warn("Component " + name + " was not imported, exported, or provided by MDXProvider as global scope")
  return <div {...props}/>
};
const layoutProps = {

};
const MDXLayout = "wrapper"
function MDXContent({
  components,
  ...props
}) {
  return <MDXLayout {...layoutProps} {...props} components={components} mdxType="MDXLayout">
    <table>
      <thead parentName="table">
        <tr parentName="thead">
          <th parentName="tr" {...{
            "align": "left"
          }}>{`Left`}</th>
          <th parentName="tr" {...{
            "align": "center"
          }}>{`Centre`}</th>
          <th parentName="tr" {...{
            "align": "right"
          }}>{`Right`}</th>
        </tr>
      </thead>
      <tbody parentName="table">
        <tr parentName="tbody">
          <td parentName="tr" {...{
            "align": "left"
          }}>{`1`}</td>
          <td parentName="tr" {...{
            "align": "center"
          }}>{`2`}</td>
          <td parentName="tr" {...{
            "align": "right"
          }}>{`3`}</td>
        </tr>
      </tbody>
    </table>
    </MDXLayout>;
}
;
MDXContent.isMDXComponent = true;

which appears to be correct.

Could you verify the node_modules folder to ensure 1.5.5 is the exact version installed? And/or could you provide a code sandbox with a runnable example of the issue? https://codesandbox.io

Everspace commented 4 years ago

Was able to pinpoint it to Theme UI. It wasn't @mdx-js/mdx's version, but the addition of theme-ui that was causing alignment to be dropped and the weird css to happen.

Here is the reproduction: https://codesandbox.io/s/ecstatic-almeida-55d90

If you comment out the "gatsby-plugin-theme-ui" this causes problems.

As far as I am aware, the only special stuff that happens is the creation of an MDXProvider with the table, tr, th, td here: https://github.com/system-ui/theme-ui/blob/master/packages/mdx/src/index.js

I'm not sure what's happening here.

ChristianMurphy commented 4 years ago

@Everspace with that MDXProvider, gatsby theme system ui is overriding mdx's default table implementation, with it's own that doesn't support the align attribute.

This is something theme ui should fix, mdx is delegating the rendering of the table, tr, td elements as expected when a MDXProvider is wrapping the content.

Everspace commented 4 years ago

Thank you. I will go over there and bother them.

denu5 commented 4 years ago

I love working with new tech, all issues you come across are usually not older than 72 hours. therefore an another question regarding tables: is it possible to somehow ugly put css code inside mdx to overwrite table styles or add classes to the table?

ChristianMurphy commented 4 years ago

There are a few options:

  1. mdx supports inline HTML, class and style attributes are supported there
  2. customize the MDXProvider with your own table, tr, td, etc. Not unlike how theme ui does
  3. add a remark or rehype plugin to add attributes or styles to the tables (see: https://unifiedjs.com/learn for information on creating a plugin)
denu5 commented 4 years ago

@ChristianMurphy thanks! actually just found the official way since I'm also using the theme-ui plugin, you can pass a style object with styles, which is the customized theme-ui provider I guess

style={{
    table: {
      width: '100%',
      borderCollapse: 'separate',
      borderSpacing: 0
    },
    th: {
      textAlign: 'left',
      borderBottomStyle: 'solid'
    },
    td: {
      textAlign: 'left',
      borderBottomStyle: 'solid'
    },
  }}
Everspace commented 4 years ago

As a workaround you may in your layout component or in wrapRootElement and all that do something like the following:

import { MDXProvider } from "@mdx-js/react"
import { Styled } from "theme-ui"

export default (props) =>
          <MDXProvider
            components={{
              table: Styled.table,
            }}
          >
            {props.children}
          </MDXProvider>