IconCollection and IconGrid

Browse Iconify collections and select icons from a virtualized grid.

Import the addon stylesheet when using addon components:

css
@import "@typlog/ui/addons";

IconCollection is a complete icon picker. It starts with the Iconify collection catalog, then opens the selected collection in its built-in virtualized IconGrid. Use v-model:collection and v-model:query when the navigation state also needs to be controlled externally.

vue
<script setup lang="ts">
import { ref } from 'vue'
import {
  Button,
  PopoverRoot,
  PopoverTrigger,
  PopoverPopup,
} from '@typlog/ui'
import { IconCollection } from '@typlog/ui/addons'

const selectedIcon = ref('')
const collection = ref('')
const query = ref('')

const onSelectIcon = (icon: string) => {
  console.info('select:', icon)
}
</script>

<template>
  <PopoverRoot>
    <Button :as="PopoverTrigger">Choose an icon</Button>
    <PopoverPopup class="w-96 p-0">
      <IconCollection
        v-model="selectedIcon"
        v-model:collection="collection"
        v-model:query="query"
        :ui="{
          browser: 'p-4',
          grid: {
            header: 'p-4',
            viewport: 'px-4',
          },
        }"
        @select="onSelectIcon"
      />
    </PopoverPopup>
  </PopoverRoot>
</template>

Examples ​

Icon grid ​

Use IconGrid directly when the collection picker is not needed and the available collection is already known.

Loading icons...

Selected: None

vue
<script setup lang="ts">
import { ref } from 'vue'
import { IconGrid } from '@typlog/ui/addons'

const selectedIcon = ref('')
</script>

<template>
  <div class="w-full max-w-xl space-y-3">
    <IconGrid
      v-model="selectedIcon"
      :collections="['lucide']"
      :height="280"
    />
    <p class="text-sm text-gray-11">
      Selected: {{ selectedIcon || 'None' }}
    </p>
  </div>
</template>

Multiple collections ​

Pass multiple prefixes to let people switch between each collection or browse all of them together.

Loading icons...

Selected: None

vue
<script setup lang="ts">
import { ref } from 'vue'
import { IconGrid } from '@typlog/ui/addons'

const selectedIcon = ref('')
const activeCollection = ref('')
</script>

<template>
  <div class="w-full max-w-xl space-y-3">
    <IconGrid
      v-model="selectedIcon"
      v-model:active-collection="activeCollection"
      :collections="['lucide', 'simple-icons']"
      :height="280"
    />
    <p class="text-sm text-gray-11">
      Selected: {{ selectedIcon || 'None' }}
    </p>
  </div>
</template>

Without collections, IconGrid searches the global Iconify index once a query is provided.

Loading icons...

Selected: None

vue
<script setup lang="ts">
import { ref } from 'vue'
import { IconGrid } from '@typlog/ui/addons'

const selectedIcon = ref('')
const query = ref('weather')
</script>

<template>
  <div class="w-full max-w-xl space-y-3">
    <IconGrid
      v-model="selectedIcon"
      v-model:query="query"
      :height="280"
    />
    <p class="text-sm text-gray-11">
      Selected: {{ selectedIcon || 'None' }}
    </p>
  </div>
</template>

Customizing parts ​

Use the ui prop to add classes to stable component parts. IconCollection accepts nested ui.grid classes for its built-in grid, while each root also accepts Vue's standard class attribute.

Loading icons...

vue
<script setup lang="ts">
import { ref } from 'vue'
import { IconGrid } from '@typlog/ui/addons'

const selectedIcon = ref('')
const query = ref('shape')
</script>

<template>
  <IconGrid
    v-model="selectedIcon"
    v-model:query="query"
    class="w-full max-w-xl overflow-hidden rounded-lg border border-gray-a4"
    :collections="['lucide', 'simple-icons']"
    :height="280"
    :ui="{
      header: 'bg-gray-a2 p-4 pb-0',
      tabs: 'mx-4',
      viewport: 'bg-gray-a2 p-4',
      cell: 'rounded-full',
    }"
  />
</template>

API Reference ​

PropDefaultType
cellSize40
number

Width and height of each icon button.

collection""
string

The current icon set prefix. An empty value displays the collection catalog.

filter""
string

The current collection catalog filter.

height420
numberstring

Height of the catalog or icon grid scroll viewport.

iconSize20
numberstring

Size of each rendered icon.

modelValue
–
string

The selected icon name, such as lucide:heart.

overscan4
number

Number of extra icon rows rendered outside the viewport.

query""
string

The current search query within the selected icon set.

ui
–
IconCollectionUI

Classes for the component's stable visual parts.

PropDefaultType
activeCollection""
string

Active collection prefix; an empty value displays all collections.

cellSize40
number

Width and height of each icon button.

collections[]
string[]

Iconify collection prefixes to display.

height420
numberstring

Height of the scroll viewport.

iconSize20
numberstring

Size of each rendered icon.

modelValue
–
string

The selected icon name, such as lucide:heart.

overscan4
number

Number of extra rows rendered outside the viewport.

query""
string

The current icon search query.

ui
–
IconGridUI

Classes for the component's stable visual parts.

Last updated Sep 15, 2026