Skip to content

Commit

Permalink
chore: refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Sep 23, 2024
1 parent 52c6b12 commit 90a8f1f
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 62 deletions.
1 change: 0 additions & 1 deletion src/components/DarkSwitcher.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ function toggleDark(event?: MouseEvent) {
Math.max(x, innerWidth - x),
Math.max(y, innerHeight - y),
)
// @ts-expect-error: Transition API
const transition = document.startViewTransition(async () => {
isDark.value = !isDark.value
await nextTick()
Expand Down
57 changes: 8 additions & 49 deletions src/components/IconDetail.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<script setup lang='ts'>
import type { BuiltInParserName } from 'prettier'
import { collections } from '../data'
import { activeMode, copyPreviewColor, getTransformedId, inBag, preferredCase, previewColor, pushRecentIcon, showCaseSelect, showHelp, toggleBag } from '../store'
import { idCases } from '../utils/case'
import { dataUrlToBlob } from '../utils/dataUrlToBlob'
import { getIconSnippet, toComponentName } from '../utils/icons'
import { getIconSnippet, SnippetMap, toComponentName } from '../utils/icons'
import { Download } from '../utils/pack'
import InstallIconSet from './InstallIconSet.vue'
Expand All @@ -24,51 +23,6 @@ const emit = defineEmits(['close', 'copy', 'next', 'prev'])
const caseSelector = ref<HTMLDivElement>()
const transformedId = computed(() => getTransformedId(props.icon))
const color = computed(() => copyPreviewColor.value ? previewColor.value : 'currentColor')
const { typeMap, handleSnippetShow } = useSnippetGroup()
function useSnippetGroup() {
const typeMap = reactive<Record<string, Record<string, {
name: string
tag?: string
code?: string
lang: string // for shiki
parser: BuiltInParserName // for prettier
}>>>(
{
Snippets: {
'svg': { name: 'SVG', lang: 'html', parser: 'html' },
'svg-symbol': { name: 'SVG Symbol', lang: 'html', parser: 'html' },
'png': { name: 'PNG', lang: 'html', parser: 'html' },
'html': { name: 'Iconify', lang: 'html', parser: 'html' },
'pure-jsx': { name: 'JSX', lang: 'jsx', parser: 'typescript' },
},
Components: {
'vue': { name: 'Vue', lang: 'vue', parser: 'vue' },
'vue-ts': { name: 'Vue', tag: 'TS', lang: 'vue', parser: 'vue' },
'jsx': { name: 'React', lang: 'jsx', parser: 'typescript' },
'tsx': { name: 'React', tag: 'TS', lang: 'tsx', parser: 'typescript' },
'svelte': { name: 'Svelte', lang: 'svelte', parser: 'typescript' },
'qwik': { name: 'Qwik', lang: 'tsx', parser: 'typescript' },
'solid': { name: 'Solid', lang: 'tsx', parser: 'typescript' },
'astro': { name: 'Astro', lang: 'astro', parser: 'typescript' },
'react-native': { name: 'React Native', lang: 'tsx', parser: 'typescript' },
'unplugin': { name: 'Unplugin Icons', lang: 'tsx', parser: 'typescript' },
},
Links: {
url: { name: 'URL', lang: 'html', parser: 'html' },
data_url: { name: 'Data URL', lang: 'html', parser: 'html' },
},
},
)
async function handleSnippetShow(group: keyof typeof typeMap, type: string) {
if (!typeMap[group][type].code) {
typeMap[group][type].code = (await getIconSnippet(props.icon, type, false, color.value))?.trim()
}
}
return { typeMap, handleSnippetShow }
}
onClickOutside(caseSelector, () => {
showCaseSelect.value = false
Expand Down Expand Up @@ -250,14 +204,19 @@ const collection = computed(() => {
</div>

<div class="flex flex-wrap mt-2">
<template v-for="(group, groupName) in typeMap" :key="groupName">
<template v-for="(group, groupName) in SnippetMap" :key="groupName">
<div class="mr-4">
<div class="my-1 op50 text-sm">
{{ groupName }}
</div>
<div class="flex gap-1">
<template v-for="(snippet, type) in group" :key="type">
<SnippetPreview :code="snippet.code" :type="type" :lang="snippet.lang" :parser="snippet.parser" @show="handleSnippetShow(groupName, type)">
<SnippetPreview
:icon="icon"
:snippet="snippet"
:type="type"
:color="color"
>
<button class="btn small opacity-75" @click="copy(type)">
{{ snippet.name }}<sup v-if="snippet.tag" class="opacity-50 -mr-1">{{ snippet.tag }}</sup>
</button>
Expand Down
4 changes: 2 additions & 2 deletions src/components/SettingsCollectionsList.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script setup lang="ts">
import type { CollectionMeta } from '../data'
import type { CollectionInfo } from '../data'
import { isInstalled } from '../data'
import { isElectron } from '../env'
import { isExcludedCategory, isExcludedCollection, isFavoritedCollection, toggleExcludedCollection, toggleFavoriteCollection } from '../store'
defineProps<{
collections: CollectionMeta[]
collections: readonly CollectionInfo[]
}>()
</script>

Expand Down
24 changes: 14 additions & 10 deletions src/components/SnippetPreview.vue
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
<script lang='ts' setup>
import type { BuiltInParserName } from 'prettier'
import { Menu } from 'floating-vue'
import { getIconSnippet, type Snippet } from '../utils/icons'
import { prettierCode } from '../utils/prettier'
import { highlight } from '../utils/shiki'
const props = defineProps<{
code: string
icon: string
snippet: Snippet
type: string
lang: string
parser: BuiltInParserName
color: string
}>()
const emit = defineEmits<{
(e: 'show'): void
}>()
const code = ref<string>('')
async function onShow() {
if (!code.value)
code.value = await getIconSnippet(props.icon, props.type, false, props.color) || ''
}
const highlightCode = computedAsync(async () => {
const code = await prettierCode(props.code, props.parser)
return highlight(code, props.lang)
const c = code.value
const formatted = await prettierCode(c, props.snippet.prettierParser)
return highlight(formatted, props.snippet.lang)
})
</script>

<template>
<Menu :delay="0" placement="top" distance="10" @show="emit('show')">
<Menu :delay="0" placement="top" distance="10" @show="onShow">
<slot />
<template #popper>
<div color-base px3 py2 border="b base" bg-gray:5>
Expand Down
1 change: 1 addition & 0 deletions src/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ body {

html.dark {
background: #181818;
color-scheme: dark;
}
html.dark .shiki,
html.dark .shiki span {
Expand Down
34 changes: 34 additions & 0 deletions src/utils/icons.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { BuiltInParserName as PrettierParser } from 'prettier'
import { encodeSvgForCss } from '@iconify/utils'
import { buildIcon, loadIcon } from 'iconify-icon'
import { getTransformedId } from '../store'
Expand All @@ -6,6 +7,39 @@ import { HtmlToJSX } from './htmlToJsx'
import { prettierCode } from './prettier'
import { svgToPngDataUrl } from './svgToPng'

export interface Snippet {
name: string
tag?: string
lang: string // for shiki
prettierParser: PrettierParser // for prettier
}

export const SnippetMap: Record<string, Record<string, Snippet>> = {
Snippets: {
'svg': { name: 'SVG', lang: 'html', prettierParser: 'html' },
'svg-symbol': { name: 'SVG Symbol', lang: 'html', prettierParser: 'html' },
'png': { name: 'PNG', lang: 'html', prettierParser: 'html' },
'html': { name: 'Iconify', lang: 'html', prettierParser: 'html' },
'pure-jsx': { name: 'JSX', lang: 'jsx', prettierParser: 'typescript' },
},
Components: {
'vue': { name: 'Vue', lang: 'vue', prettierParser: 'vue' },
'vue-ts': { name: 'Vue', tag: 'TS', lang: 'vue', prettierParser: 'vue' },
'jsx': { name: 'React', lang: 'jsx', prettierParser: 'typescript' },
'tsx': { name: 'React', tag: 'TS', lang: 'tsx', prettierParser: 'typescript' },
'svelte': { name: 'Svelte', lang: 'svelte', prettierParser: 'typescript' },
'qwik': { name: 'Qwik', lang: 'tsx', prettierParser: 'typescript' },
'solid': { name: 'Solid', lang: 'tsx', prettierParser: 'typescript' },
'astro': { name: 'Astro', lang: 'astro', prettierParser: 'typescript' },
'react-native': { name: 'React Native', lang: 'tsx', prettierParser: 'typescript' },
'unplugin': { name: 'Unplugin Icons', lang: 'tsx', prettierParser: 'typescript' },
},
Links: {
url: { name: 'URL', lang: 'html', prettierParser: 'html' },
data_url: { name: 'Data URL', lang: 'html', prettierParser: 'html' },
},
}

const API_ENTRY = 'https://api.iconify.design'

export async function getSvgLocal(icon: string, size = '1em', color = 'currentColor') {
Expand Down

0 comments on commit 90a8f1f

Please sign in to comment.