Skip to content

Instantly share code, notes, and snippets.

@RobinMalfait

RobinMalfait/README.md Secret

Last active Oct 22, 2020
Embed
What would you like to do?
Tailwind UI -> Valid React

Community based - Examples to React

DISCLAIMER: This is something a Tailwind UI user created. This also doesn't actually add all the functionality, however it will ensure that the markup is valid JSX. Search for todo and you will see all the alpine stuff that you can convert yourself.


WARNING: This doesn't work in Firefox because they don't allow to read from the clipboard. They only allow it in extensions.

How to use

  1. Create a bookmark in your browser where the url is set to the contents of bookmark.js 1.1. Copy bookmark.js

    1.2. Create a new bookmark in your browser. I am using Brave here.

    1.3. Paste in the contents

  2. Go to Tailwind UI

  3. Press the "Copy to clipboard" button on an example

  4. Press the bookmark

  5. You should receive an alert saying that it is either copied OR has an error.

  6. Profit.

javascript:window.navigator.clipboard.readText().then((data)=>{return window.navigator.clipboard.writeText(data .replace(/class=/g,"className=").replace(/ @([^"]*)=/g,(_all,group)=>` data-todo-at-${group.replace(/[.:]/g,"-")}=`).replace(/ x-([^ "]*)/g,(_all,group)=>` data-todo-x-${group.replace(/[.:]/g,"-")}`).replace(/<!--/g,"{/*").replace(/-->/g,"*/}").replace(/tabindex="([^"]*)"/g,"tabIndex={$1}").replace(/datetime=/g,"dateTime=").replace(/clip-rule=/g,"clipRule=").replace(/fill-rule=/g,"fillRule=").replace(/stroke-linecap=/g,"strokeLinecap=").replace(/stroke-width=/g,"strokeWidth=").replace(/stroke-linejoin=/g,"strokeLinejoin=").replace(/for=/g,"htmlFor=").replace(/ :(.*)=/g," data-todo-colon-$1=").replace(/href="#"/g,'href="/"').replace(/src="\//g,'src="https://tailwindui.com/').replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"").replace(/<(img|input|hr)([^>]*)>/g,"<$1$2 />").replace(/style="([^"]*)"/g,(_,style)=>{return `style={{${style.split(";").filter((pair)=>pair.trim().length).map((pair)=>pair.split(":").map((part)=>part.trim())).map(([key,value])=>[key.replace(/-(\w)/g,(_,v)=>v.toUpperCase()),JSON.stringify(value.match(/\d*px/)?parseFloat(value):value)].join(": ")).join(", ")}}}`}).trim()).then(()=>{alert("Copied to clipboard!")})}).catch((err)=>{console.log("[TAILWIND UI - Example -> React] Error:",err);alert("Bummer! Something went wrong... (psst, see devtools)")});
// Note this doesn't work as a bookmark, you need the bookmark (minified) version
javascript: window.navigator.clipboard
.readText()
.then((data) => {
return window.navigator.clipboard
.writeText(
data
// Replace `class=` with `className=`
.replace(/class=/g, "className=")
// Replace all attributes starting with @.
//
// E.g.: `@click.stop` -> `data-todo-at-stop`
.replace(
/ @([^"]*)=/g,
(_all, group) => ` data-todo-at-${group.replace(/[.:]/g, "-")}=`
)
// Replaces all attributes starting with x-.
//
// E.g.: `x-transition:enter` -> `data-todo-x-transition-enter`
.replace(
/ x-([^ "]*)/g,
(_all, group) => ` data-todo-x-${group.replace(/[.:]/g, "-")}`
)
// Replace html comments with JSX comments
.replace(/<!--/g, "{/*")
.replace(/-->/g, "*/}")
// Replace `tabindex="0"` with `tabIndex={0}`
.replace(/tabindex="([^"]*)"/g, "tabIndex={$1}")
// Replace `datetime` with `dateTime` for <time />
.replace(/datetime=/g, "dateTime=")
// Replace `clip-rule` with `clipRule` in svg's
.replace(/clip-rule=/g, "clipRule=")
// Replace `fill-rule` with `fillRule` in svg's
.replace(/fill-rule=/g, "fillRule=")
// Replace `stroke-linecap` with `strokeLinecap` in svg's
.replace(/stroke-linecap=/g, "strokeLinecap=")
// Replace `stroke-width` with `strokeWidth` in svg's
.replace(/stroke-width=/g, "strokeWidth=")
// Replace `stroke-linejoin` with `strokeLinejoin` in svg's
.replace(/stroke-linejoin=/g, "strokeLinejoin=")
// Replace `for` with `htmlFor` in forms
.replace(/for=/g, "htmlFor=")
// Replace all attributes starting with :.
//
// E.g.`:class="{ 'hidden': open, 'inline-flex': !open` ->
// `data-todo-colon-class="{ 'hidden': open, 'inline-flex': !open }"`
.replace(/ :(.*)=/g, " data-todo-colon-$1=")
// Replace `href="#"` with `href="/"` (Otherwise Create React App complains)
.replace(/href="#"/g, 'href="/"')
// Replace relative src paths with absolute src paths.
.replace(/src="\//g, 'src="https://tailwindui.com/')
// Drop scripts ¯\_(ツ)_/¯
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "")
// Ensure img, input and hr tags are self closed
.replace(/<(img|input|hr)([^>]*)>/g, "<$1$2 />")
// Ensure we rewrite the style string to an object
.replace(/style="([^"]*)"/g, (_, style) => {
return `style={{${style
.split(";")
.filter((pair) => pair.trim().length)
.map((pair) => pair.split(":").map((part) => part.trim()))
.map(([key, value]) =>
[
key.replace(/-(\w)/g, (_, v) => v.toUpperCase()),
JSON.stringify(
value.match(/\d*px/) ? parseFloat(value) : value
),
].join(": ")
)
.join(", ")}}}`;
})
// Trim the whitespace!
.trim()
)
.then(() => {
alert("Copied to clipboard!");
});
})
.catch((err) => {
console.log("[TAILWIND UI - Example -> React] Error:", err);
alert("Bummer! Something went wrong... (psst, see devtools)");
});
@mokadev

This comment has been minimized.

Copy link

@mokadev mokadev commented Feb 28, 2020

Hi

thanks for this Gist!

You should add a replacement for stroke-linecap (=> strokeLinecap), stroke-linejoin (=> strokeLinejoin) and stroke-width (=> strokeWidth)

@waldothedeveloper

This comment has been minimized.

Copy link

@waldothedeveloper waldothedeveloper commented Mar 2, 2020

I cannot understand step 1 at all. Can you put it visually like a screenshot or something?

@RobinMalfait

This comment has been minimized.

Copy link
Owner Author

@RobinMalfait RobinMalfait commented Mar 2, 2020

@waldothedeveloper do you know how to add a bookmark to your browser's bookmarks bar?

@waldothedeveloper

This comment has been minimized.

Copy link

@waldothedeveloper waldothedeveloper commented Mar 2, 2020

@RobinMalfait,

yes I do ....is this what you mean?

image

Perhaps I didn't formulate my question correctly.

I'd say that the rest of the steps don't work for me.
That's why I asked you for like a step by step screenshots.

@RobinMalfait

This comment has been minimized.

Copy link
Owner Author

@RobinMalfait RobinMalfait commented Mar 2, 2020

@waldothedeveloper but if you figured that out, what exactly is the "the steps don't work for me", what do you have issues with?

I updated the readme with images, if this doesn't help you than I can't help you further.

@waldothedeveloper

This comment has been minimized.

Copy link

@waldothedeveloper waldothedeveloper commented Mar 2, 2020

@RobinMalfait thank you for adding the screenshots, I appreciate that.

@vvo

This comment has been minimized.

Copy link

@vvo vvo commented Mar 12, 2020

Hey thanks this is extremely useful :)

@vvo

This comment has been minimized.

Copy link

@vvo vvo commented Mar 12, 2020

@RobinMalfait and others, I made a small UI to explain how to use this, with an easy drag and drop button https://qlp8g.csb.app/

@rylandking

This comment has been minimized.

Copy link

@rylandking rylandking commented Mar 22, 2020

Thank you for this, @RobinMalfait!

@JuanLuisGarciaBorrego

This comment has been minimized.

Copy link

@JuanLuisGarciaBorrego JuanLuisGarciaBorrego commented Apr 20, 2020

Hello, thanks you!
How do you implement the effects in ReactJS?

<div className={`md:hidden ${showNav ? 'block' : 'hidden'} `}></div>

 {/*<!--
    Off-canvas menu overlay, show/hide based on off-canvas menu state.

   Entering: "transition-opacity ease-linear duration-300"
   From: "opacity-0"
  To: "opacity-100"
  Leaving: "transition-opacity ease-linear duration-300"
   From: "opacity-100"
   To: "opacity-0"
-->*/}
@vvo

This comment has been minimized.

@JuanLuisGarciaBorrego

This comment has been minimized.

Copy link

@JuanLuisGarciaBorrego JuanLuisGarciaBorrego commented Apr 20, 2020

@vvo thank you very much!!

@rgdelato

This comment has been minimized.

Copy link

@rgdelato rgdelato commented May 16, 2020

Just a quick FYI, it might be worth adding a note that this snippet doesn't work in Firefox, at least as far as I can tell.

@impulse

This comment has been minimized.

Copy link

@impulse impulse commented Aug 14, 2020

Made a grease/tampermonkey script with minor modifications: Tailwind UI -> Valid React

Preview:
ezgif-4-37af9c68da35

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.