Skip to content

Instantly share code, notes, and snippets.

@kiliman
Last active March 31, 2021 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kiliman/9f590f748dd24da2f4fa58705994a2d0 to your computer and use it in GitHub Desktop.
Save kiliman/9f590f748dd24da2f4fa58705994a2d0 to your computer and use it in GitHub Desktop.
Tampermonkey script to copy SVG/JSX with specific classes
// ==UserScript==
// @name Heroicons copy
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://heroicons.com
// @icon https://www.google.com/s2/favicons?domain=tampermonkey.net
// @grant none
// ==/UserScript==
;(function () {
'use strict'
const snakeToCamel = str =>
str.replace(/([-_][a-z])/g, group =>
group.toUpperCase().replace('-', '').replace('_', ''),
)
const re = /-(svg|jsx)$/
const reJsx = /-jsx$/
const reAttrib = /\s+([-\w]+)=/g
// don't include height/width as they will be computed by icon size
const defaultClass = 'text-gray-500'
document.addEventListener('click', function (e) {
if (!re.test(e.target.id)) return
const isJsx = reJsx.test(e.target.id)
const id = e.target.id.replace(re, '-btn')
const btn = document.getElementById(id)
if (btn) {
let icon = btn.innerHTML
let classAttrib = 'class'
// get current icon height to compute the size
const height = icon.match(/height="(\d+)"/)[1]
const size = parseInt(height) / 4
const newClass = `h-${size} w-${size} ${defaultClass}`
// remove height and width attributes
icon = icon.replace(/(height|width)="[^"]+"\s*/g, '')
// get class so we can move it to start of <svg/> tag
const match = icon.match(/\s*class="[^"]+"/)
let currentClass = match ? match[0] : ''
// remove existing class
icon = icon.replace(currentClass, '')
// append to start of tag
icon = icon.replace('<svg ', `<svg ${currentClass.trim()} `)
if (isJsx) {
// convert snake-case attributes to camelCase
icon = icon.replace(reAttrib, (_, p1) => ` ${snakeToCamel(p1)}=`)
classAttrib = 'className'
}
icon = icon.replace(/class="[^"]+"/, `${classAttrib}="${newClass}"`)
icon = format(icon)
console.log(icon)
navigator.clipboard.writeText(icon)
}
})
function format(html) {
const tab = ' '
let result = ''
let indent = ''
html.split(/>\s*</).forEach(function (element) {
if (element.match(/^\/\w/)) {
indent = indent.substring(tab.length)
}
const breakLine = !element.startsWith('path')
const doIndent = !element.startsWith('/path')
result +=
(doIndent ? indent : '') + '<' + element + '>' + (breakLine ? '\n' : '')
if (element.match(/^<?\w[^>]*[^\/]$/) && !element.startsWith('input')) {
indent += tab
}
})
return result.substring(1, result.length - 2) + '\n'
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment