html-react-parser icon indicating copy to clipboard operation
html-react-parser copied to clipboard

important style is not parsed

Open piszczu4 opened this issue 1 year ago • 13 comments

The following is not parsed when using attributesToProps(domNode.attribs):

style="margin-left: 24px!important"

while this is:

style="margin-left: 24px"

Why is that a case?

piszczu4 avatar Feb 09 '24 00:02 piszczu4

@piszczu4 this is expected behavior because this library parses inline styles and inline styles do not support !important

remarkablemark avatar Feb 09 '24 01:02 remarkablemark

@piszczu4 this is expected behavior because this library parses inline styles and inline styles do not support !important

Why does not support? Look here: https://codepen.io/degel123/pen/poYOLzE

piszczu4 avatar Feb 09 '24 01:02 piszczu4

@piszczu4 can you provide a reproducible example of this not working for you?

remarkablemark avatar Feb 09 '24 02:02 remarkablemark

Here it is: https://codesandbox.io/p/sandbox/parser-hf4g76?file=%2Fsrc%2FApp.tsx%3A30%2C44-30%2C53

If you remove !important, it starts to work.

piszczu4 avatar Feb 09 '24 12:02 piszczu4

@piszczu4 I can't seem to open the CodeSandbox?

Screen Shot 2024-02-09 at 10 41 02 AM

remarkablemark avatar Feb 09 '24 15:02 remarkablemark

Try this: https://codesandbox.io/p/sandbox/parser-hf4g76?file=%2Fsrc%2FApp.tsx

Here is the code:

import * as Popover from "@radix-ui/react-popover";
import * as Tooltip from "@radix-ui/react-tooltip";
import * as React from "react";
import { forwardRef, ReactNode } from "react";
import "./styles.css";

import parse, {
  DOMNode,
  Element,
  HTMLReactParserOptions,
  attributesToProps,
  domToReact,
} from "html-react-parser";

export default function App() {
  const options = {
    replace(domNode: DOMNode) {
      if (!(domNode instanceof Element)) return domNode;

      if (domNode.tagName === "p") {
        return (
          <p {...attributesToProps(domNode.attribs)}>
            {domToReact(domNode.children as DOMNode[], options)}
          </p>
        );
      }
    },
  };

  const html = `<p style="margin-left:24px!important">Example</p>`;
  return <div className="App">{parse(html, options)}</div>;
}

piszczu4 avatar Feb 09 '24 17:02 piszczu4

Any feeedbaack?

piszczu4 avatar Feb 12 '24 12:02 piszczu4

Any progress on that one?

piszczu4 avatar Feb 29 '24 02:02 piszczu4

Hello Guys, are you going to fix the issue?

ArtsiomReutovich avatar Apr 04 '24 04:04 ArtsiomReutovich

I've been really busy these days so I haven't had a chance to look into this. If anyone has a solution, feel free to open a PR and I can review it.

I did a quick search and it looks like React does not support important inline styles: https://stackoverflow.com/questions/23074748/important-inline-styles-in-react

remarkablemark avatar Apr 04 '24 05:04 remarkablemark

Hello @remarkablemark,

In our case, the problem is mostly related to some styles being missed after it was processed by the plugin.

For instance, we have node: <span style="color:red!important;font-size:14px">Text</span>

After the conversion becomes: <span style="font-size:14px">Text</span>

As you can see "color" style is missing. Can we have the possibility of "saving" style even if it was passed with "!important"? like: <span style="color:red;font-size:14px">Text</span>

ArtsiomReutovich avatar Apr 04 '24 07:04 ArtsiomReutovich

@ArtsiomReutovich can replace work as a workaround for you? If it doesn't, a quick hack would be to do a replaceAll('!important', '') for your HTML string.

remarkablemark avatar Apr 04 '24 17:04 remarkablemark

Hello @remarkablemark, Yes, I'm doing it this way.

ArtsiomReutovich avatar Apr 05 '24 04:04 ArtsiomReutovich