feat: more optimize for electron

This commit is contained in:
Anthony Fu 2020-07-17 14:57:05 +08:00
parent 73c97b2768
commit c3cf4f048d
27 changed files with 10174 additions and 10762 deletions

3
.gitignore vendored
View File

@ -7,4 +7,5 @@ src/assets/collections.json
public/collections
public/collections-info.json
public/collections-meta.json
public/collections-meta.json
public/lib

View File

@ -3,7 +3,7 @@
<p align="center">Explorer for <a href="https://iconify.design/" target="_blank">Iconify</a> with <b>Instant</b> searching.</p>
<p align="center">
<a href="https://iconify.antfu.me/">iconify.antfu.me</a>
<a href="https://iconify.antfu.me/">iconify.antfu.me</a>
</p>
![](./screenshots/1.png)

View File

@ -1,5 +1,5 @@
{
"name": "electron-webpack-quick-start",
"name": "iconify-explorer-electron",
"version": "0.0.0",
"license": "MIT",
"scripts": {
@ -9,6 +9,7 @@
"dist:dir": "yarn dist --dir -c.compression=store -c.mac.identity=null"
},
"dependencies": {
"babel-loader": "^8.1.0",
"electron-debug": "^3.1.0",
"electron-serve": "^1.0.0",
"electron-util": "^0.14.2",

View File

@ -17,7 +17,7 @@ const createMainWindow = async() => {
height: 500,
minWidth: 200,
minHeight: 200,
titleBarStyle: 'hidden',
titleBarStyle: 'hiddenInset',
})
win.on('ready-to-show', () => {

File diff suppressed because it is too large Load Diff

View File

@ -4,9 +4,8 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Iconify Explorer</title>
<script src="https://code.iconify.design/1/1.0.7/iconify.without-api.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/svg-packer@latest/dist/index.browser.min.js" defer></script>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
<script src="/lib/iconify.min.js"></script>
<script src="/lib/svg-packer.js" defer></script>
</head>
<body class="dragging">
<div id="app"></div>

View File

@ -3,8 +3,10 @@
"version": "0.0.0",
"private": true,
"scripts": {
"preinstall": "npx only-allow pnpm",
"postinstall": "ts-node -P tsconfig.tsnode.json scripts/prepare.ts",
"dev": "vite",
"dev:electron": "pnpm -C ./electron dev",
"build": "vite build"
},
"dependencies": {
@ -15,6 +17,8 @@
"vue-router": "next"
},
"devDependencies": {
"svg-packer": "^0.0.3",
"@iconify/iconify": "^1.0.7",
"@antfu/eslint-config-vue": "^0.2.13",
"@iconify/json": "^1.1.186",
"@types/fs-extra": "^9.0.1",

9822
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

2
pnpm-workspace.yaml Normal file
View File

@ -0,0 +1,2 @@
packages:
- 'electron/'

View File

@ -1,11 +1,12 @@
import path from 'path'
import fs from 'fs-extra'
const dir = path.resolve(__dirname, '../node_modules/@iconify/json')
const out = path.resolve(__dirname, '../public')
const collectionsDir = path.resolve(__dirname, '../public/collections')
async function prepare() {
async function prepareJSON() {
const dir = path.resolve(__dirname, '../node_modules/@iconify/json')
const collectionsDir = path.resolve(__dirname, '../public/collections')
const raw = await fs.readJSON(path.join(dir, 'collections.json'))
await fs.ensureDir(collectionsDir)
@ -21,9 +22,12 @@ async function prepare() {
const icons = Object.keys(setData.icons)
const categories = setData.categories
const meta = {...info, icons, categories }
const meta = { ...info, icons, categories }
await fs.writeJSON(path.join(collectionsDir, `${info.id}-raw.json`), setData)
await fs.writeJSON(
path.join(collectionsDir, `${info.id}-raw.json`),
setData
)
await fs.writeJSON(path.join(collectionsDir, `${info.id}-meta.json`), meta)
collectionsMeta.push(meta)
@ -34,4 +38,29 @@ async function prepare() {
await fs.writeJSON(path.join(out, 'collections-info.json'), collections)
}
async function copyLibs() {
const modules = path.resolve(__dirname, '../node_modules')
await fs.copy(
path.join(modules, '@iconify/iconify/dist/'),
path.join(out, 'lib'),
{
filter: (src) => {
if (fs.lstatSync(src).isDirectory()) return true
const basename = path.basename(src)
return basename.startsWith('iconify') && basename.endsWith('.min.js')
}
}
)
await fs.copy(
path.join(modules, 'svg-packer/dist/index.browser.js'),
path.join(out, 'lib/svg-packer.js')
)
}
async function prepare() {
await prepareJSON()
await copyLibs()
}
prepare()

View File

@ -1,10 +1,7 @@
<template>
<div class="flex flex-col h-screen overflow-hidden" :style="style">
<div class="flex flex-auto overflow-hidden">
<Drawer v-if="!isRoot" class="h-full overflow-auto flex-none hidden md:block" style="width:280px" />
<div class="h-full flex-auto overflow-auto">
<router-view />
</div>
<div class="h-full flex-auto overflow-auto">
<router-view />
</div>
</div>
</template>
@ -16,17 +13,13 @@ import { themeColor } from './store'
export default defineComponent({
setup() {
const route = useRoute()
const isRoot = computed(() => route.path === '/')
const style = computed(() => ({
'--theme-color': themeColor.value,
'--theme-color': themeColor.value
}))
return {
isRoot,
style,
style
}
},
}
})
</script>

View File

@ -1,5 +1,5 @@
<template>
<div class="h-full flex flex-col" style="width:40vw;">
<div class="h-full flex flex-col w-screen md:w-16">
<div class="flex-none border-b border-gray-200 py-3 px-6 flex">
<div>
<div class="text-gray-700 text-lg">
@ -10,7 +10,7 @@
</div>
</div>
<div class="flex-auto" />
<IconButton class="text-xl mr-4 flex-none" icon="carbon:delete" @click="clear" />
<IconButton v-if='bags.length' class="text-xl mr-4 flex-none" icon="carbon:delete" @click="clear" />
<IconButton class="text-2xl flex-none" icon="carbon:close" @click="$emit('close')" />
</div>
<template v-if="bags.length">
@ -18,8 +18,8 @@
<Icons :icons="bags" />
</div>
<div class="flex-none border-t border-gray-200 py-3 px-6 text-2xl text-gray-700">
<IconButton class="p-1" icon="carbon:function" text="Generate Icon Fonts" :active="true" @click="pack()" />
<IconButton class="p-1" icon="carbon:download" text="Download All SVGs" :active="true" @click="wip" />
<IconButton class="p-1 cursor-pointer" icon="carbon:function" text="Generate Icon Fonts" :active="true" @click="pack()" />
<IconButton class="p-1 cursor-pointer" icon="carbon:download" text="Download All SVGs" :active="true" @click="wip" />
</div>
</template>
<template v-else>

View File

@ -1,6 +1,8 @@
<template>
<div class="border-r border-gray-200">
<!-- Back button, Mobile Only -->
<div
v-if='!isElectron'
class="border-b border-gray-200"
>
<IconButton
@ -10,6 +12,8 @@
@click="$router.replace('/')"
/>
</div>
<!-- Collections -->
<router-link
v-for="collection in collections"
:key="collection.id"
@ -46,6 +50,7 @@ import { defineComponent, computed } from 'vue'
import { useRoute } from 'vue-router'
import { sortedCollectionsInfo } from '../data'
import { isFavorited, toggleFavorite } from '../store'
import { isElectron } from '../env'
export default defineComponent({
setup() {
@ -64,6 +69,7 @@ export default defineComponent({
current,
toggleFavorite,
isFavorited,
isElectron,
}
},
})

View File

@ -0,0 +1,33 @@
<template>
<div class="electron-nav dragging md:border-b border-gray-200 flex-none flex justify-start">
<div class="mac-controls flex-none" />
<IconButton
v-show="$route.path !== '/'"
class="text-lg mx-1 px-3 flex-none"
icon="carbon:chevron-left"
@click="$router.replace('/')"
/>
<div class="inline-block text-sm text-gray-800 my-auto ml-3 font-light"><b class="font-bold">Iconify</b>Explorer</div>
<div class="flex-auto"></div>
</div>
</template>
<script lang='ts'>
import { defineComponent } from 'vue'
export default defineComponent({})
</script>
<style>
.electron-nav {
height: 37px
}
.mac-controls {
width: 70px;
}
.electron-nav .icon-button svg {
margin-top: -2px;
}
</style>

View File

@ -1,6 +1,6 @@
<template>
<div class="hidden md:block p-4 m-6 fixed bottom-0 right-0 shadow-lg bg-white rounded-full text-2xl cursor-pointer hover:bg-gray-100">
<div class="p-4 m-6 fixed bottom-0 right-0 shadow-lg bg-white rounded-full text-2xl cursor-pointer hover:bg-gray-100">
<Icon class="text-gray-700" :icon="icon" />
<div
v-if="number"

View File

@ -1,6 +1,6 @@
<template>
<div
class="m-auto cursor-pointer"
class="icon-button m-auto"
:class="active ? 'opacity-100 hover:opacity-100 hover:text-primary' : 'opacity-25 hover:opacity-50' "
>
<Icon

View File

@ -1,10 +1,10 @@
<template>
<div class="non-dragging flex flex-wrap select-none justify-center" :class="`text-${size}`" :style="{ color }">
<div class="non-dragging flex flex-wrap select-none justify-center" :class="`text-${size}`">
<div
v-for="icon of icons"
:key="icon"
class="non-dragging icons-item cursor-pointer flex m-2"
:class="selected.includes(namespace+icon) ? 'active': ''"
class="non-dragging icons-item flex"
:class="[spacing, selected.includes(namespace+icon) ? 'active': '']"
@click="$emit('select', namespace+icon)"
>
<Icon class="non-dragging" :icon="namespace+icon" />
@ -33,14 +33,14 @@ export default defineComponent({
type: String,
default: '2xl',
},
spacing: {
type: String,
default: 'm-2'
},
search: {
type: String,
default: '',
},
color: {
type: String,
default: '#555',
},
display: {
type: String,
default: 'grid',

View File

@ -6,7 +6,7 @@
@click="$emit('close')"
/>
<div
class="bg-white absolute shadow-lg transition-all duration-200 ease-out border-gray-200"
class="bg-white absolute transition-all duration-200 ease-out border-gray-200"
:class="positionClass"
:style="value ? {}: {transform}"
>

View File

@ -0,0 +1,71 @@
<template>
<div class="px-1 text-xl text-gray-800 flex">
<IconButton
class="mr-3"
icon="carbon:checkbox-checked"
:active="selectingMode"
@click="selectingMode = !selectingMode"
/>
<div class="mx-1 h-full m-auto bg-gray-200" style="width:1px;" />
<IconButton
class="ml-3"
icon="carbon:hinton-plot"
title="Small"
:active="listType === 'grid' && iconSize === '2xl'"
@click="()=>setGrid('small')"
/>
<IconButton
class="ml-3"
icon="carbon:app-switcher"
title="Large"
:active="listType === 'grid' && iconSize === '4xl'"
@click="()=>setGrid('large')"
/>
<IconButton
class="ml-3"
icon="carbon:list"
title="List View"
:active="listType === 'list'"
@click="()=>setGrid('list')"
/>
</div>
</template>
<script lang='ts'>
import { defineComponent, PropType } from 'vue'
import { iconSize, listType, showCategories, selectingMode } from '../store'
import { CollectionMeta } from '../data'
export default defineComponent({
props: {
collection: {
type: Object as PropType<CollectionMeta>
}
},
setup() {
const setGrid = (type: string) => {
switch (type) {
case 'small':
iconSize.value = '2xl'
listType.value = 'grid'
break
case 'large':
iconSize.value = '4xl'
listType.value = 'grid'
break
default:
iconSize.value = '3xl'
listType.value = 'list'
}
}
return {
setGrid,
listType,
iconSize,
showCategories,
selectingMode
}
}
})
</script>

View File

@ -1,6 +1,7 @@
<template>
<div class="flex h-screen flex-col overflow-hidden">
<Navbar :class="navClass" />
<ElectronNav v-if='isElectron'/>
<Navbar v-else :class="navClass" />
<div class="flex-auto overflow-auto">
<slot />
</div>
@ -9,13 +10,23 @@
<script lang='ts'>
import { defineComponent } from 'vue'
import ElectronNav from './ElectronNav.vue'
import { isElectron } from '../env'
export default defineComponent({
components: {
ElectronNav
},
props: {
navClass: {
type: String,
default: '',
},
},
setup(){
return {
isElectron,
}
}
})
</script>

1
src/env.ts Normal file
View File

@ -0,0 +1 @@
export const isElectron = location.protocol === 'app:' || (process.env.NODE_ENV === 'development' && navigator.userAgent.indexOf('Electron') >= 0)

View File

@ -15,6 +15,7 @@ import Footer from './components/Footer.vue'
import FAB from './components/FAB.vue'
import Drawer from './components/Drawer.vue'
import Bag from './components/Bag.vue'
import ViewControls from './components/ViewControls.vue'
import './main.css'
const app = createApp(App)
@ -52,5 +53,6 @@ app.component('Footer', Footer)
app.component('Drawer', Drawer)
app.component('FAB', FAB)
app.component('Bag', Bag)
app.component('ViewControls', ViewControls)
app.mount('#app')

View File

@ -1,7 +1,7 @@
<template>
<div v-if="!collection" class="p-4 text-gray-700">
Loading...
</div>
<WithNavbar v-if="!collection">
<div class="py-8 px-4 text-gray-700 text-center">Loading...</div>
</WithNavbar>
<IconSet v-else :collection="collection" :installed="installed" />
</template>
@ -13,19 +13,19 @@ import {
getFullMeta,
install,
getMeta,
CollectionMeta,
CollectionMeta
} from '../data'
import IconSet from './IconSet.vue'
export default defineComponent({
components: {
IconSet,
IconSet
},
props: {
id: {
type: String,
required: true,
},
required: true
}
},
setup(props) {
const loaded = ref(isMetaLoaded(props.id))
@ -34,7 +34,7 @@ export default defineComponent({
watch(
() => props.id,
async() => {
async () => {
loaded.value = false
if (props.id === 'all') {
@ -42,23 +42,22 @@ export default defineComponent({
collection.value = {
id: 'all',
name: 'All',
icons: meta.flatMap(c => c.icons.map(i => `${c.id}:${i}`)),
icons: meta.flatMap(c => c.icons.map(i => `${c.id}:${i}`))
}
}
else {
} else {
await install(props.id)
collection.value = await getMeta(props.id)
}
loaded.value = true
},
{ immediate: true },
{ immediate: true }
)
return {
collection,
loaded,
installed,
installed
}
},
}
})
</script>

View File

@ -1,150 +1,107 @@
<template>
<WithNavbar nav-class="md:hidden">
<div class="py-5 px-5 md:px-8">
<div class="flex">
<!-- Left -->
<div class="flex-auto">
<div class="text-gray-900 text-xl flex">
{{ collection.name }}
<a
v-if="collection.url"
class="text-gray-500 hover:text-gray-900 mt-1 text-base"
:href="collection.url"
target="_blank"
>
<Icon icon="la:external-link-square-alt-solid" />
</a>
<div class="flex flex-auto h-full overflow-hidden">
<Drawer class="h-full overflow-auto flex-none hidden md:block" style="width:280px" />
<div class="py-5 px-5 md:px-8 h-full overflow-y-auto">
<div class="flex">
<!-- Left -->
<div class="flex-auto">
<div class="text-gray-900 text-xl flex">
{{ collection.name }}
<a
v-if="collection.url"
class="text-gray-500 hover:text-gray-900 mt-1 text-base"
:href="collection.url"
target="_blank"
>
<Icon icon="la:external-link-square-alt-solid" />
</a>
<div class="flex-auto" />
</div>
<div class="text-gray-500 text-xs block">{{ collection.author }}</div>
<div>
<a
class="text-gray-500 text-xs hover:text-gray-900"
:href="collection.licenseURL"
target="_blank"
>{{ collection.license }}</a>
</div>
</div>
<!-- Right -->
<div class="flex flex-col">
<ViewControls :collection="collection" />
<div class="flex-auto" />
</div>
<div class="text-gray-500 text-xs block">
{{ collection.author }}
</div>
<div>
<a
class="text-gray-500 text-xs hover:text-gray-900"
:href="collection.licenseURL"
target="_blank"
>{{ collection.license }}</a>
</div>
</div>
<!-- Right -->
<div class="flex flex-col">
<div class="px-1 text-xl text-gray-800 flex">
<IconButton
class="hidden md:block mr-3"
icon="carbon:checkbox-checked"
:active="selectingMode"
@click="selectingMode = !selectingMode"
/>
<div class="hidden md:block mx-1 h-full m-auto bg-gray-200" style="width:1px;" />
<template v-if="collection.categories">
<IconButton
class="mx-3"
icon="carbon:categories"
:active="showCategories"
title="Categories"
@click="showCategories = !showCategories"
/>
<div class="mx-1 m-auto h-full bg-gray-200" style="width:1px;" />
</template>
<IconButton
class="ml-3"
icon="carbon:hinton-plot"
title="Small"
:active="listType === 'grid' && iconSize === '2xl'"
@click="()=>setGrid('small')"
/>
<IconButton
class="ml-3"
icon="carbon:app-switcher"
title="Large"
:active="listType === 'grid' && iconSize === '4xl'"
@click="()=>setGrid('large')"
/>
<IconButton
class="ml-3"
icon="carbon:list"
title="List View"
:active="listType === 'list'"
@click="()=>setGrid('list')"
/>
</div>
<div class="flex-auto" />
<!-- Categories -->
<div class="py-3 pr-3 overflow-x-auto flex flex-no-wrap">
<template v-if="collection.categories">
<div
v-for="c of Object.keys(collection.categories)"
:key="c"
class="whitespace-no-wrap text-sm inline-block px-2 border border-gray-200 text-gray-500 rounded-full m-1 hover:bg-gray-100 cursor-pointer"
:class="c === category ? 'text-primary border-primary' : ''"
@click="toggleCategory(c)"
>{{ c }}</div>
</template>
</div>
</div>
<!-- Categories -->
<div class="py-2">
<template v-if="collection.categories && showCategories">
<div
v-for="c of Object.keys(collection.categories)"
:key="c"
class="text-sm inline-block px-2 border border-gray-200 text-gray-500 rounded-full m-1 hover:bg-gray-100 cursor-pointer"
:class="c === category ? 'text-primary border-primary' : ''"
@click="toggleCategory(c)"
>
{{ c }}
</div>
</template>
</div>
<!-- Search -->
<div class="flex">
<input
v-model="search"
class="shadow rounded outline-none py-2 px-4 flex-auto"
placeholder="Search..."
/>
</div>
<!-- Search -->
<div class="flex">
<input
v-model="search"
class="shadow rounded outline-none py-2 px-4 flex-auto"
placeholder="Search..."
>
</div>
<!-- Icons -->
<div class="py-4 text-center">
<Icons
:icons="icons.slice(0, max)"
:selected="selectedIcons"
:size="iconSize"
:display="listType"
:search="search"
:namespace="namespace"
style="color: #666"
@select="onSelect"
/>
<button v-if="icons.length > max" class="btn m-2" @click="loadMore">Load More</button>
<p class="text-gray-500 text-sm pt-4">{{ icons.length }} icons</p>
</div>
<!-- Icons -->
<div class="py-4 text-center">
<Icons
:icons="icons.slice(0, max)"
:selected="selectedIcons"
:size="iconSize"
:display="listType"
:search="search"
:namespace="namespace"
@select="onSelect"
<Footer />
<!-- Details -->
<Modal :value="!!current" @close="current = null">
<IconDetail :icon="current" />
</Modal>
<!-- Bag -->
<Modal :value="showBag" direction="right" @close="showBag = false">
<Bag @close="showBag = false" />
</Modal>
<!-- Bag Fab -->
<FAB
v-if="bags.length"
icon="carbon:shopping-bag"
:number="bags.length"
@click="showBag = true"
/>
<button v-if="icons.length > max" class="btn m-2" @click="loadMore">
Load More
</button>
<p class="text-gray-500 text-sm px-2">
{{ icons.length }} icons
</p>
</div>
<Footer />
<!-- Details -->
<Modal :value="!!current" @close="current = null">
<IconDetail :icon="current" />
</Modal>
<!-- Bag -->
<Modal :value="showBag" direction="right" @close="showBag = false">
<Bag @close="showBag = false" />
</Modal>
<!-- Bag Fab -->
<FAB
v-if="bags.length"
icon="carbon:shopping-bag"
:number="bags.length"
@click="showBag = true"
/>
<!-- Selecting Note -->
<div
class="fixed top-0 right-0 pl-4 pr-2 py-1 rounded-l-full bg-primary text-white shadow mt-16 cursor-pointer transition-transform duration-300 ease-in-out"
:style="selectingMode ? {} : {transform: 'translateX(120%)'}"
@click="selectingMode = false"
>
Selecting Mode
<Icon icon="carbon:close" class="inline-block text-xl align-text-bottom" />
<!-- Selecting Note -->
<div
class="fixed top-0 right-0 pl-4 pr-2 py-1 rounded-l-full bg-primary text-white shadow mt-16 cursor-pointer transition-transform duration-300 ease-in-out"
:style="selectingMode ? {} : {transform: 'translateX(120%)'}"
@click="selectingMode = false"
>
Selecting Mode
<Icon icon="carbon:close" class="inline-block text-xl align-text-bottom" />
</div>
</div>
</div>
</WithNavbar>
@ -152,16 +109,25 @@
<script lang='ts'>
import { defineComponent, ref, toRefs, computed, PropType } from 'vue'
import { iconSize, listType, showCategories, selectingMode, bags, toggleBag } from '../store'
import {
iconSize,
listType,
showCategories,
selectingMode,
bags,
toggleBag
} from '../store'
import { useSearch } from '../hooks/search'
import { CollectionMeta } from '../data'
import { useRoute } from 'vue-router'
import { isElectron } from '../env'
export default defineComponent({
props: {
collection: {
type: Object as PropType<CollectionMeta>,
required: true,
},
required: true
}
},
setup(props) {
const { collection } = toRefs(props)
@ -169,13 +135,11 @@ export default defineComponent({
const showBag = ref(false)
const current = ref<string | null>(null)
const max = ref(200)
const max = ref(isElectron ? 500 : 200)
const toggleCategory = (cat: string) => {
if (category.value === cat)
category.value = ''
else
category.value = cat
if (category.value === cat) category.value = ''
else category.value = cat
}
const namespace = computed(() => {
@ -183,39 +147,19 @@ export default defineComponent({
})
const onSelect = (icon: string) => {
if (selectingMode.value)
toggleBag(icon)
else
current.value = icon
if (selectingMode.value) toggleBag(icon)
else current.value = icon
}
const selectedIcons = computed(() => {
if (selectingMode.value)
return bags.value
else
return current.value ? [] : [current.value]
if (selectingMode.value) return bags.value
else return current.value ? [] : [current.value]
})
const loadMore = () => {
max.value += 100
}
const setGrid = (type: string) => {
switch (type) {
case 'small':
iconSize.value = '2xl'
listType.value = 'grid'
break
case 'large':
iconSize.value = '4xl'
listType.value = 'grid'
break
default :
iconSize.value = '3xl'
listType.value = 'list'
}
}
return {
current,
search,
@ -227,7 +171,6 @@ export default defineComponent({
loadMore,
iconSize,
listType,
setGrid,
namespace,
selectedIcons,
@ -238,8 +181,8 @@ export default defineComponent({
// bags
showBag,
bags,
selectingMode,
selectingMode
}
},
}
})
</script>

View File

@ -1,36 +1,35 @@
<template>
<WithNavbar>
<div class="">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
<div class="collections-list grid">
<div
v-for="collection in collections"
:key="collection.id"
class="px-2 py-4 border-r border-b border-gray-200"
>
<router-link
v-for="collection in collections"
:key="collection.id"
class="flex flex-col relative transition-all duration-300 text-gray-900 text-center justify-center hover:text-primary"
:to="`/collection/${collection.id}`"
>
<div class="flex flex-col py-4 relative border-r border-b border-gray-200 transition-all duration-300 text-gray-900 hover:text-primary">
<div class="flex-auto bg-opacity-50 text-center">
<div class="text-lg">
{{ collection.name }}
</div>
<div class="text-gray-500 text-sm block leading-none">
{{ collection.author }}
</div>
</div>
<Icons
:icons="collection.sampleIcons"
:namespace="`${collection.id}:`"
class="py-2 justify-center overflow-hidden flex-none pointer-events-none"
/>
<div class="flex-auto bg-opacity-50 text-center">
<div class="text-gray-500 text-xs block">
{{ collection.license }}
</div>
<div class="text-gray-500 text-xs block">
{{ collection.total }} icons
</div>
</div>
<IconButton v-if="isFavorited(collection.id)" class="absolute top-0 right-0 p-2 text-lg" icon="carbon:bookmark" />
<div class="flex-auto text-lg">{{ collection.name }}</div>
<div class="flex-auto opacity-50 text-xs">
<span>{{ collection.author }}</span>
<span class="px-1 opacity-25">/</span>
<span>{{ collection.license }}</span>
<span class="px-1 opacity-25">/</span>
<span>{{ collection.total }} icons</span>
</div>
<Icons
:icons="collection.sampleIcons"
:namespace="`${collection.id}:`"
size="xl"
spacing="m-1"
class="mt-2 mb-1 justify-center opacity-75 overflow-hidden flex-none pointer-events-none"
/>
<IconButton
v-if="isFavorited(collection.id)"
class="absolute top-0 right-0 p-2 text-lg"
icon="carbon:bookmark"
/>
</router-link>
</div>
</div>
@ -49,8 +48,14 @@ export default defineComponent({
return {
collections: sortedCollectionsInfo,
isFavorited,
sample,
sample
}
},
}
})
</script>
<style>
.collections-list {
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
</style>

View File

@ -24,9 +24,6 @@ module.exports = {
},
theme: {
extend: {
fontFamily: {
sans: ['Roboto', ...defaultTheme.fontFamily.sans],
},
fontSize: {
'7xl': '5rem',
'8xl': '6rem',

3622
yarn.lock

File diff suppressed because it is too large Load Diff