From c844bc668f624bf43060c88d85fa244fc630ef66 Mon Sep 17 00:00:00 2001 From: Eric Fennis Date: Wed, 28 Jun 2023 21:04:37 +0200 Subject: [PATCH] Small fixes site (#1408) --- .../theme/components/base/Tooltip.vue | 55 ++++++++++ .../theme/components/icons/CopySVGButton.vue | 45 +------- .../theme/components/icons/IconGrid.vue | 1 + .../theme/components/icons/IconItem.vue | 102 ++++++++++-------- .../theme/composables/useConfetti.ts | 4 +- docs/.vitepress/theme/utils/downloadData.ts | 6 ++ docs/.vitepress/theme/utils/getSVGIcon.ts | 34 ++++++ docs/guide/packages/lucide-react.md | 2 +- docs/package.json | 1 + pnpm-lock.yaml | 23 ++++ 10 files changed, 183 insertions(+), 90 deletions(-) create mode 100644 docs/.vitepress/theme/components/base/Tooltip.vue create mode 100644 docs/.vitepress/theme/utils/downloadData.ts create mode 100644 docs/.vitepress/theme/utils/getSVGIcon.ts 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 @@ + + + + + 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}`) } } +