☢ dangerous
A utility function to create a dangerous/unsafe React component using tagged literal
templates.
The syntax is borrowed from Styled Components.
dangerous
returns a component, which uses
dangerouslySetInnerHTML
internally to convert your dangerous input to set literal to DOM's innerHTML
value.
⚠️ Requirement
Minimum required version of React is v16.3.0 because dangerous
uses React.forwardRef, which was introduced in v16.3.0.
Installation
$ npm i dangerous
$ yarn add dangerous
✍ Usage
👶 Basic Usage
You can pass raw HTML to dangerous
using tagged template literal.
const DangerousComponent = dangerous.div`💖 & 🕊`;
const DangerousComponent = dangerous('div')`💖 & 🕊`
You can Subtitute div
with any valid DOM elements or a custom React component.
const DangerousComponent = dangerous.span`💖 & 🕊`
const DangerousComponent = dangerous.p`💖 & 🕊`
const DangerousComponent = dangerous.section`💖 & 🕊`
const DangerousComponent = dangerous(CustomComponent)`💖 & 🕊`
Render Result
Dangerous component will set &emp;
directly so the rendered result will show
💖 & 🕊
while React will render it as
💖 & 🕊
as shown below.
🐱👤 Advanced Usage
dangerous
returns a React component, to which you can pass props, which you can access within tagged template literal.
const DangerousComponent = dangerous.div`
<h1>Who am I?</h1>
<p>Last Name is "${props => props.lastName}"</p>
<p>First Name is "${props => props.firstName}"</p>
<a href="javascript:alert('${({ firstName, lastName }) =>
`Hi ${firstName} ${lastName}`}');">Show Alert</a>`;
function App() {
return <DangerousComponent firstName="Sung" lastName="Kim" />;
}
In the code above, <DangerousComponent />
is passed following props in App
.
firstName="Sung"
lastName="Kim"
You can access the props in the tagged literal using ${props => props.properyName}
.
This was taken directly from Styled Component syntax.
And you can destructure props and combine it to compose any string you want.
const DangerousComponent = dangerous.div`
//... omitted for brevity
<a href="javascript:alert('${({ firstName, lastName }) => `Hi ${firstName} ${lastName}`}');">Show Alert</a>`;
⤵ Return object
dangerous
returns a React component and behaves like a HoC (High-order Component).
If a custom component is passed to dangerous
, then all static properties will be hoisted down to the wrapped component.
👨💻 Example
The example below shows how to use dangerous
with a custom Block
components with static properties and Styled Components, StyledDangerous
& StyledBlock
.
It also demo's wrapping StyledBlock
(a Styled Component component 😅) with dangerous
as DangerousStyled
.
import React from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";
import dangerous from "dangerous";
import "./styles.css";
class Block extends React.Component {
static count = 10;
static increaseCount = () => console.log(++Block.count);
static decreaseCount = () => console.log(--Block.count);
render() {
return <div {...this.props} />;
}
}
const Dangerous = dangerous.div`
<h1>Who am I?</h1>
<p>Last Name is "${props => props.lastName}"</p>
<p>First Name is "${props => props.firstName}"</p>
<a href="javascript:alert('${({ firstName, lastName }) =>
`Hi ${firstName} ${lastName}`}');">Show Alert</a>`;
const StyledDangerous = styled(Dangerous)`
background-color: papayawhip;
padding: 1.5em 0;
`;
const StyledBlock = styled(Block)`
background-color: hotpink;
padding: 1.5em 0;
`;
const DangerousStyled = dangerous(StyledBlock)`
<h1>Alter Ego</h1>
<p>Click link below to find out who my alter ego is</p>
<a href="javascript:alert('${props => props.name}');">Show Aleter Ego Name</a>
`;
function App() {
return (
<div className="App">
<section>
<StyledDangerous firstName="Sung" lastName="Kim" />
<DangerousStyled name="dance2die" />
</section>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
🥊 Demo in action
💪 To Dos
- Create a GitHub project for version 1.
- Add TypeScript types
- Add TypeScript definition files to distribution
- Add tests
- Update Logo to look as stylish as that of Styled Components's. 😄