Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Is it a normal behavior to have all element properties stringified (through hast-to-hyperscript) ? #41

@medfreeman

Description

@medfreeman

Hi, thanks for your work !!

here's a bit of context.

I'm developing a common mark generic extensions plugin, supporting this kind of syntax:
!Element[content](argument){ properties }

I'm using !Icon[My-tooltip](my-icon){ floating } for testing

My remark inline tokenizer returns this node:

{
  type: 'extension',
  data: {
    hName: 'Icon',
    hProperties: {
      tooltip: 'My-tooltip',
      icon: 'my-icon'
      floating: true
    },
  }
})

Notice the boolean property named floating.

I can properly have my corresponding react component TooltipIcon render with the following snippet (es6):

import remark from "remark"
import reactRenderer from "remark-react"
import merge from "deepmerge"
import sanitizeGhSchema from "hast-util-sanitize/lib/github.json"

import TooltipIcon from "../TooltipIcon"
import genericExtensions from "./remark-commonmark-generic-extensions.js"

remark()
    .use(genericExtensions, {
      elements: {
        Icon: {
          attributeMap: {
            content: "tooltip",
            argument: "icon",
          },
          attributeDefaultValues: {
            floating: true,
          }
        }
      }
    })
    .use(reactRenderer, {
      sanitize: merge(sanitizeGhSchema, {
        tagNames: [
          "Icon",
        ],
        attributes: {
          Icon: [
            "className",
            "tooltip",
            "icon",
            "floating",
          ],
        },
      }),
      remarkReactComponents: {
        Icon: TooltipIcon
      },
    })
    .processSync(body, {
      commonmark: true,
    })

Whereas my floating property is effectively boolean inside the HAST tree generated by remark, it is stringified by hast-to-hyperscript at this line, called here in remark-react.

In order to avoid a react PropTypes type warning, i'm actually forced to also allow String in addition to Boolean propTypes for the floating property inside my component. I then coerce the floating property back to boolean, in order for the subcomponent (which requires floating to be boolean) to be happy.

Here's my TooltipIcon component:

import React, { PropTypes } from "react"
import IconButton from "react-toolbox/lib/button"
import Tooltip from "react-toolbox/lib/tooltip"

const TooltipButton = Tooltip(IconButton)

const TooltipIcon = props => {

  const { floating, ...otherProps } = props
  if (floating === "true") {
    otherProps.floating = true
  }

  return (
    <TooltipButton
      { ...otherProps }
    />
  )
}

TooltipIcon.propTypes = {
  floating: PropTypes.oneOfType([
    PropTypes.bool,
    PropTypes.string,
  ]),
  tooltip: PropTypes.any,
  theme: PropTypes.object,
}

export default TooltipIcon

I hope you get the general idea, and if you can tell if it's a requirement to have every property stringified.
Because in this case only String properties can be passed to React if i'm not mistaken.

Metadata

Metadata

Assignees

No one assigned

    Labels

    👀 no/externalThis makes more sense somewhere else

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions