Skip to content

Commit bc97b34

Browse files
feat: use Ic icon on custom inspector/tab/command (#466)
Co-authored-by: Alex <[email protected]> Co-authored-by: Alex <[email protected]>
1 parent c753696 commit bc97b34

File tree

24 files changed

+2398
-110
lines changed

24 files changed

+2398
-110
lines changed

docs/plugins/api.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ $ bun add -D @vue/devtools-api
3131

3232
## `addCustomTab`
3333

34+
You can choose any icon from [Material Design Icons](https://fonts.google.com/icons) or [Iconify Ic Baseline](https://icones.netlify.app/collection/ic?variant=Baseline), for example `star`.
35+
3436
```ts
3537
import { addCustomTab } from '@vue/devtools-api'
3638

@@ -39,8 +41,8 @@ addCustomTab({
3941
name: 'vue-use',
4042
// title to display in the tab
4143
title: 'VueUse',
42-
// any icon from Iconify, or a URL to an image
43-
icon: 'i-logos-vueuse',
44+
// any icon from material design icons or a URL to an image
45+
icon: 'https://vueuse.org/favicon.svg',
4446
// iframe view
4547
view: {
4648
type: 'iframe',
@@ -52,6 +54,8 @@ addCustomTab({
5254

5355
## `addCustomCommand`
5456

57+
You can choose any icon from [Material Design Icons](https://fonts.google.com/icons) or [Iconify Ic Baseline](https://icones.netlify.app/collection/ic?variant=Baseline), for example `star`.
58+
5559
```ts
5660
import { addCustomCommand } from '@vue/devtools-api'
5761

@@ -61,8 +65,8 @@ addCustomCommand({
6165
id: 'vueuse',
6266
// title to display in the command
6367
title: 'VueUse',
64-
// any icon from Iconify, or a URL to an image
65-
icon: 'i-logos-vueuse',
68+
// any icon from material design icons or a URL to an image
69+
icon: 'https://vueuse.org/favicon.svg',
6670
action: {
6771
type: 'url',
6872
src: 'https://vueuse.org/'
@@ -75,14 +79,13 @@ addCustomCommand({
7579
id: 'vueuse',
7680
// title to display in the command
7781
title: 'VueUse',
78-
// any icon from Iconify, or a URL to an image
79-
icon: 'i-logos-vueuse',
82+
// any icon from material design icons or a URL to an image
83+
icon: 'https://vueuse.org/favicon.svg',
8084
// submenu, which is shown when the menu is clicked
8185
children: [
8286
{
8387
id: 'vueuse:github',
8488
title: 'Github',
85-
icon: 'i-carbon-logo-github',
8689
action: {
8790
type: 'url',
8891
src: 'https://github.com/vueuse/vueuse'
@@ -91,7 +94,7 @@ addCustomCommand({
9194
{
9295
id: 'vueuse:website',
9396
title: 'Website',
94-
icon: 'i-logos-vueuse',
97+
icon: 'auto-awesome',
9598
action: {
9699
type: 'url',
97100
src: 'https://vueuse.org/'

packages/applet/src/modules/custom-inspector/components/state/Index.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Pane, Splitpanes } from 'splitpanes'
44
import { DevToolsMessagingEvents, onRpcConnected, rpc } from '@vue/devtools-core'
55
import { parse } from '@vue/devtools-kit'
66
import type { CustomInspectorNode, CustomInspectorOptions, CustomInspectorState } from '@vue/devtools-kit'
7-
import { vTooltip } from '@vue/devtools-ui'
7+
import { VueIcIcon, vTooltip } from '@vue/devtools-ui'
88
import { until } from '@vueuse/core'
99
import Navbar from '~/components/basic/Navbar.vue'
1010
import DevToolsHeader from '~/components/basic/DevToolsHeader.vue'
@@ -186,7 +186,7 @@ onUnmounted(() => {
186186
<div v-if="actions?.length" class="mb-1 flex justify-end pb-1" border="b dashed base">
187187
<div class="flex items-center gap-2 px-1">
188188
<div v-for="(action, index) in actions" :key="index" v-tooltip.bottom-end="{ content: action.tooltip }" class="flex items-center gap1" @click="callAction(index)">
189-
<i :class="`i-ic-baseline-${action.icon.replace(/\_/g, '-')}`" cursor-pointer op70 text-base hover:op100 />
189+
<VueIcIcon :name="`baseline-${action.icon.replace(/\_/g, '-')}`" cursor-pointer op70 text-base hover:op100 />
190190
</div>
191191
</div>
192192
</div>
@@ -200,7 +200,7 @@ onUnmounted(() => {
200200
<div v-if="nodeActions?.length" class="mb-1 flex justify-end pb-1" border="b dashed base">
201201
<div class="flex items-center gap-2 px-1">
202202
<div v-for="(action, index) in nodeActions" :key="index" v-tooltip.bottom-end="{ content: action.tooltip }" class="flex items-center gap1" @click="callNodeAction(index)">
203-
<i :class="`i-ic-baseline-${action.icon.replace(/\_/g, '-')}`" cursor-pointer op70 text-base hover:op100 />
203+
<VueIcIcon :name="`baseline-${action.icon.replace(/\_/g, '-')}`" cursor-pointer op70 text-base hover:op100 />
204204
</div>
205205
</div>
206206
</div>

packages/applet/src/modules/custom-inspector/index.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ const routes = computed(() => {
3535
path: '/about',
3636
name: 'About',
3737
component: About,
38-
icon: 'https://raw.githubusercontent.com/TanStack/query/main/packages/vue-query/media/vue-query.svg',
3938
},
4039
].filter(Boolean) as VirtualRoute[]
4140
})

packages/client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
},
2626
"dependencies": {
2727
"@unocss/preset-icons": "^0.61.0",
28-
"@unocss/runtime": "^0.61.0",
2928
"@vue/devtools-applet": "workspace:^",
3029
"@vue/devtools-core": "workspace:^",
3130
"@vue/devtools-kit": "workspace:^",
@@ -34,6 +33,7 @@
3433
"@vueuse/core": "^10.11.0",
3534
"@vueuse/integrations": "^10.11.0",
3635
"colord": "^2.9.3",
36+
"fast-deep-equal": "^3.1.3",
3737
"fuse.js": "^7.0.0",
3838
"minimatch": "^9.0.4",
3939
"shiki": "^1.9.0",

packages/client/src/App.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { Pane, Splitpanes } from 'splitpanes'
33
import { useDevToolsColorMode } from '@vue/devtools-ui'
44
import { DevToolsMessagingEvents, onDevToolsConnected, onRpcConnected, refreshCurrentPageData, rpc, useDevToolsState } from '@vue/devtools-core'
55
6-
import('./setup/unocss-runtime')
76
useDevToolsColorMode()
87
const router = useRouter()
98
const route = useRoute()

packages/client/src/components/common/SideNav.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ const overflowTabs = computed(() => flattenedTabs.value.slice(containerCapacity.
2222
const categorizedInlineTabs = getCategorizedTabs(inlineTabs, enabledTabs)
2323
const categorizedOverflowTabs = getCategorizedTabs(overflowTabs, enabledTabs)
2424
25-
const displayedTabs = computed(() => (sidebarScrollable.value || sidebarExpanded.value)
26-
? enabledTabs.value
27-
: categorizedInlineTabs.value)
25+
const displayedTabs = computed(() =>
26+
(sidebarScrollable.value || sidebarExpanded.value)
27+
? enabledTabs.value
28+
: categorizedInlineTabs.value,
29+
)
2830
2931
onClickOutside(
3032
panel,

packages/client/src/components/common/SideNavItem.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function onClick() {
5555
text-xl
5656
:icon="tab.icon"
5757
:fallback="tab.fallbackIcon"
58-
title="Settings"
58+
:title="tab.name"
5959
:show-title="false"
6060
/>
6161
<span v-if="!minimized" text-md overflow-hidden text-ellipsis ws-nowrap>

packages/client/src/components/common/TabIcon.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<script setup lang="ts">
2+
import { isUrlString } from '@vue/devtools-shared'
3+
import { VueIcIcon } from '@vue/devtools-ui'
4+
25
const props = withDefaults(defineProps<{
36
icon?: string
47
title?: string
@@ -13,11 +16,14 @@ const _icon = ref<string | undefined>(props.icon)
1316
function onLoadError() {
1417
_icon.value = props.fallback
1518
}
19+
20+
// For custom-inspector icons, the prefix is 'custom-ic-'
21+
const CUSTOM_IC_ICON_PREFIX = 'custom-ic-'
1622
</script>
1723

1824
<template>
1925
<img
20-
v-if="_icon && (_icon.startsWith('/') || _icon.match(/^https?:/))"
26+
v-if="_icon && isUrlString(_icon)"
2127
:style="{
2228
width: '1em',
2329
height: '1em',
@@ -27,6 +33,10 @@ function onLoadError() {
2733
:alt="title"
2834
@error="onLoadError"
2935
>
36+
<VueIcIcon
37+
v-else-if="_icon?.startsWith(CUSTOM_IC_ICON_PREFIX)" :name="_icon.slice(CUSTOM_IC_ICON_PREFIX.length)"
38+
v-bind="$attrs" :title="showTitle ? title : undefined"
39+
/>
3040
<div
3141
v-else
3242
:style="{

packages/client/src/composables/custom-inspector-tabs.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { useCustomInspector } from '@vue/devtools-applet'
2-
// @ts-expect-error skip type check
32
import type { CustomInspectorType } from '@vue/devtools-applet'
43

54
import type { ModuleBuiltinTab } from '~/types/tab'

packages/client/src/composables/state-commands.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { randomStr } from '@vue/devtools-shared'
22
import { CustomCommand } from '@vue/devtools-kit'
33
import { MaybeRefOrGetter } from 'vue'
44
import { useDevToolsState } from '@vue/devtools-core'
5+
import equal from 'fast-deep-equal'
56

67
export interface CommandItem {
78
id: string
@@ -26,17 +27,21 @@ export function useCommands() {
2627
const router = useRouter()
2728
const state = useDevToolsState()
2829

29-
const customCommands = ref<CustomCommand[]>(state.commands.value || [])
30+
let cachedCustomCommands: CustomCommand[] = []
3031

31-
watchEffect(() => {
32-
customCommands.value = state.commands.value || []
32+
const customCommands = computed(() => {
33+
if (equal(state.commands.value, cachedCustomCommands))
34+
// Optimized computed value
35+
return cachedCustomCommands
36+
cachedCustomCommands = state.commands.value
37+
return state.commands.value
3338
})
3439

3540
const fixedCommands: CommandItem[] = [
3641
{
3742
id: 'fixed:settings',
3843
title: 'Settings',
39-
icon: 'carbon-settings-adjust',
44+
icon: 'i-carbon-settings-adjust',
4045
action: () => {
4146
router.push('/settings')
4247
},
@@ -129,10 +134,10 @@ export async function getVueDocsCommands() {
129134
if (!_vueDocsCommands) {
130135
const list = await import('../../data/vue-apis.json').then(i => i.default)
131136
_vueDocsCommands = list.map(i => ({
132-
...i,
133-
icon: 'carbon-api-1',
137+
...i!,
138+
icon: 'i-carbon-api-1',
134139
action: () => {
135-
window.open(i.url, '_blank')
140+
window.open(i!.url, '_blank')
136141
},
137142
}))
138143
}

0 commit comments

Comments
 (0)