diff --git a/docs/.vitepress/theme/components/base/Tooltip.vue b/docs/.vitepress/theme/components/base/Tooltip.vue
new file mode 100644
index 000000000..4371bb7fe
--- /dev/null
+++ b/docs/.vitepress/theme/components/base/Tooltip.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+ {{title}}
+
+
+
+
diff --git a/docs/.vitepress/theme/components/icons/CopySVGButton.vue b/docs/.vitepress/theme/components/icons/CopySVGButton.vue
index b5c74828c..882ab677d 100644
--- a/docs/.vitepress/theme/components/icons/CopySVGButton.vue
+++ b/docs/.vitepress/theme/components/icons/CopySVGButton.vue
@@ -3,19 +3,9 @@ import { ref } from 'vue';
import ButtonMenu from '../base/ButtonMenu.vue'
import { useIconStyleContext } from '../../composables/useIconStyle';
import useConfetti from '../../composables/useConfetti';
+import getSVGIcon from '../../utils/getSVGIcon';
+import downloadData from '../../utils/downloadData';
-const allowedAttrs = [
- 'xmlns',
- 'width',
- 'height',
- 'viewBox',
- 'fill',
- 'stroke',
- 'stroke-width',
- 'stroke-linecap',
- 'stroke-linejoin',
- 'class',
-]
const downloadText = 'Download!'
const copiedText = 'Copied!'
const confettiText = ref(copiedText)
@@ -28,24 +18,6 @@ const { size } = useIconStyleContext()
const { animate, confetti } = useConfetti()
-function getSVGIcon() {
- const svg = document.querySelector('#previewer svg')
- if (!svg) return
-
- const clonedSvg = svg.cloneNode(true) as SVGElement
-
- // Filter out attributes that are not allowed in SVGs
- for (const attr of Array.from(clonedSvg.attributes)) {
- if (!allowedAttrs.includes(attr.name)) {
- clonedSvg.removeAttribute(attr.name)
- }
- }
-
- const svgString = new XMLSerializer().serializeToString(clonedSvg)
-
- return svgString
-}
-
function copySVG() {
confettiText.value = copiedText
const svgString = getSVGIcon()
@@ -70,11 +42,7 @@ function downloadSVG() {
confettiText.value = downloadText
const svgString = getSVGIcon()
- const link = document.createElement('a');
- link.download = `${props.name}.svg`;
- link.href = `data:image/svg+xml;base64,${btoa(svgString)}`
- link.click();
-
+ downloadData(`${props.name}.svg`, `data:image/svg+xml;base64,${btoa(svgString)}`)
confetti()
}
@@ -91,12 +59,7 @@ function downloadPNG() {
image.src = `data:image/svg+xml;base64,${btoa(svgString)}`;
image.onload = function() {
ctx.drawImage(image, 0, 0);
-
- const link = document.createElement('a');
- link.download = `${props.name}.png`;
- link.href = canvas.toDataURL('image/png')
- link.click();
-
+ downloadData(`${props.name}.png`, canvas.toDataURL('image/png'))
confetti()
}
}
diff --git a/docs/.vitepress/theme/components/icons/IconGrid.vue b/docs/.vitepress/theme/components/icons/IconGrid.vue
index 363faecde..9842c3969 100644
--- a/docs/.vitepress/theme/components/icons/IconGrid.vue
+++ b/docs/.vitepress/theme/components/icons/IconGrid.vue
@@ -43,5 +43,6 @@ function setActiveIcon(name: string) {
.icon {
aspect-ratio: 1/1;
+ position: relative;
}
diff --git a/docs/.vitepress/theme/components/icons/IconItem.vue b/docs/.vitepress/theme/components/icons/IconItem.vue
index a2f300430..96c92f82c 100644
--- a/docs/.vitepress/theme/components/icons/IconItem.vue
+++ b/docs/.vitepress/theme/components/icons/IconItem.vue
@@ -2,13 +2,17 @@
import createLucideIcon from 'lucide-vue-next/src/createLucideIcon';
import { useMediaQuery } from '@vueuse/core';
import { useRouter } from 'vitepress';
+import getSVGIcon from '../../utils/getSVGIcon';
+import useConfetti from '../../composables/useConfetti';
+import Tooltip from '../base/Tooltip.vue';
+
+const downloadText = 'Download!'
+const copiedText = 'Copied!'
export type IconNode = [elementName: string, attrs: Record][]
const props = defineProps<{
name: string;
- // tags: string[];
- // categories: string[];
iconNode: IconNode;
active: boolean;
customizable?: boolean;
@@ -20,40 +24,65 @@ const emit = defineEmits(['setActiveIcon'])
const { go } = useRouter()
const showOverlay = useMediaQuery('(min-width: 860px)');
+const { animate, confetti, confettiText } = useConfetti()
+
const icon = createLucideIcon(props.name, props.iconNode)
-function navigateToIcon() {
+async function navigateToIcon(event) {
+
+ if (event.shiftKey) {
+ event.preventDefault()
+ const svgString = getSVGIcon(event.target.firstChild, {
+ class: `lucide lucide-${props.name}`,
+ })
+
+ await navigator.clipboard.writeText(svgString)
+
+ confettiText.value = copiedText
+ confetti()
+ return
+ }
+
if(props.overlayMode && showOverlay.value) {
+ event.preventDefault()
window.history.pushState({}, '', `/icons/${props.name}`)
emit('setActiveIcon', props.name)
}
else {
+ event.preventDefault()
go(`/icons/${props.name}`)
}
}
-
+
+
+
+
+
+
+
+
+