Skip to content

Commit a2d20bf

Browse files
authored
feat(core): render group dock accentColor on group button and popover (#509)
1 parent dccb218 commit a2d20bf

5 files changed

Lines changed: 58 additions & 6 deletions

File tree

packages/core/src/client/webcomponents/components/dock/DockEntry.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
import type { DevToolsDockEntryBase } from '@vitejs/devtools-kit'
33
import type { DocksContext } from '@vitejs/devtools-kit/client'
44
import { useEventListener } from '@vueuse/core'
5-
import { useTemplateRef } from 'vue'
5+
import { computed, useTemplateRef } from 'vue'
66
import { setFloatingTooltip } from '../../state/floating-tooltip'
7+
import { accentTextStyle } from '../../utils/accent-color'
78
import { openDockContextMenu } from './DockContextMenu'
89
import DockIcon from './DockIcon.vue'
910
@@ -17,12 +18,17 @@ const props = withDefaults(
1718
isVertical?: boolean
1819
badge?: string
1920
tooltip?: boolean
21+
/** A `group` entry's optional `accentColor`, applied while selected/active. */
22+
accentColor?: string
2023
}>(),
2124
{
2225
tooltip: true,
2326
},
2427
)
2528
29+
// Only kicks in while selected — an idle group button keeps its default look.
30+
const accentStyle = computed(() => (props.isSelected ? accentTextStyle(props.accentColor) : undefined))
31+
2632
const button = useTemplateRef<HTMLButtonElement>('button')
2733
2834
function updateTooltip() {
@@ -78,10 +84,11 @@ useEventListener('pointerdown', () => {
7884
<button
7985
ref="button"
8086
:aria-label="dock.title"
87+
:style="accentStyle"
8188
:class="[
8289
isVertical ? 'rotate-270' : '',
8390
isDimmed ? 'op50 saturate-0' : '',
84-
isSelected ? 'scale-120 text-primary' : '',
91+
isSelected ? (accentColor ? 'scale-120' : 'scale-120 text-primary') : '',
8592
isAction ? 'bg-[#8881] hover:bg-[#8882] rounded-full' : 'rounded-xl',
8693
]"
8794
class="flex items-center justify-center p1.5 hover:bg-[#8881] hover:scale-110 transition-all duration-300 relative outline-none"

packages/core/src/client/webcomponents/components/dock/DockGroupButton.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ function onClick() {
127127
:is-selected="isActive || isPanelVisible"
128128
:is-dimmed="dimInactive && selected ? !isActive : false"
129129
:badge="group.badge"
130+
:accent-color="group.accentColor"
130131
@click="onClick"
131132
/>
132133
</div>

packages/core/src/client/webcomponents/components/dock/DockGroupPopover.vue

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import type { DevToolsDockEntriesGrouped, DevToolsDockEntry, DevToolsViewGroup } from '@vitejs/devtools-kit'
33
import type { DocksContext } from '@vitejs/devtools-kit/client'
44
import { computed } from 'vue'
5+
import { accentActiveStyle, accentTextStyle } from '../../utils/accent-color'
56
import DockIcon from './DockIcon.vue'
67
78
const props = defineProps<{
@@ -17,11 +18,17 @@ const emit = defineEmits<{
1718
}>()
1819
1920
const isEmpty = computed(() => props.members.every(([, items]) => items.length === 0))
21+
22+
const headerStyle = computed(() => accentTextStyle(props.group.accentColor))
23+
24+
function memberStyle(memberId: string) {
25+
return props.selectedId === memberId ? accentActiveStyle(props.group.accentColor) : undefined
26+
}
2027
</script>
2128

2229
<template>
2330
<div class="flex flex-col gap-0.5 min-w-44 max-w-64" @mousemove.stop>
24-
<div class="flex items-center gap-1.5 px4 mx--2 pt2 pb2.5 font-bold text-2.75 uppercase tracking-wide border-b border-base">
31+
<div class="flex items-center gap-1.5 px4 mx--2 pt2 pb2.5 font-bold text-2.75 uppercase tracking-wide border-b border-base" :style="headerStyle">
2532
<DockIcon :icon="group.icon" class="w-4.5 h-4.5" />
2633
<span class="truncate">{{ group.title }}</span>
2734
</div>
@@ -32,7 +39,8 @@ const isEmpty = computed(() => props.members.every(([, items]) => items.length =
3239
v-for="member of items"
3340
:key="member.id"
3441
class="flex items-center gap-2 w-full px2 py1.5 rounded text-sm text-left transition"
35-
:class="selectedId === member.id ? 'text-primary bg-active' : 'op80 hover:op100 hover:bg-active'"
42+
:class="selectedId === member.id ? (group.accentColor ? '' : 'text-primary bg-active') : 'op80 hover:op100 hover:bg-active'"
43+
:style="memberStyle(member.id)"
3644
@click="emit('select', member)"
3745
>
3846
<DockIcon :icon="member.icon" class="w-4.5 h-4.5 flex-none" />

packages/core/src/client/webcomponents/components/dock/DockGroupSidebar.vue

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { computed, h, ref, useTemplateRef } from 'vue'
66
import { deriveSidebarCapacity, docksSplitGroupsWithCapacity, getGroupMembersGrouped } from '../../state/dock-settings'
77
import { sharedStateToRef } from '../../state/docks'
88
import { setDocksSidebarOverflowPanel, setFloatingTooltip, useDocksSidebarOverflowPanel } from '../../state/floating-tooltip'
9+
import { accentActiveStyle, accentTextStyle } from '../../utils/accent-color'
910
import DockGroupPopover from './DockGroupPopover.vue'
1011
import DockIcon from './DockIcon.vue'
1112
@@ -125,13 +126,22 @@ watchDebounced(
125126
126127
// Highlight the button when the hidden selection lives here, or while open.
127128
const moreButtonActive = computed(() => selectedInOverflow.value || isOverflowPanelVisible.value)
129+
130+
// Accent styling, mirroring DockGroupPopover: falls back to the default
131+
// Uno classes below when the group sets no `accentColor`.
132+
const anchorStyle = computed(() => accentTextStyle(props.group.accentColor))
133+
function memberStyle(memberId: string) {
134+
return props.selectedId === memberId ? accentActiveStyle(props.group.accentColor) : undefined
135+
}
136+
const moreButtonStyle = computed(() => (moreButtonActive.value ? accentActiveStyle(props.group.accentColor) : undefined))
128137
</script>
129138

130139
<template>
131140
<div ref="sidebar" class="vite-devtools-group-sidebar flex flex-col flex-none w-12 h-full border-r border-base of-y-hidden of-x-hidden select-none py1.5 items-center gap-0.5">
132141
<!-- Group anchor -->
133142
<div
134143
class="flex items-center justify-center w-8 h-8 op60"
144+
:style="anchorStyle"
135145
@pointerenter="showTooltip($event, group.title)"
136146
@pointerleave="hideTooltip"
137147
>
@@ -148,7 +158,8 @@ const moreButtonActive = computed(() => selectedInOverflow.value || isOverflowPa
148158
:key="member.id"
149159
:aria-label="member.title"
150160
class="relative flex items-center justify-center w-8 h-8 rounded-lg transition"
151-
:class="selectedId === member.id ? 'text-primary bg-active' : 'op60 hover:op100 hover:bg-active'"
161+
:class="selectedId === member.id ? (group.accentColor ? '' : 'text-primary bg-active') : 'op60 hover:op100 hover:bg-active'"
162+
:style="memberStyle(member.id)"
152163
@pointerenter="showTooltip($event, member.title)"
153164
@pointerleave="hideTooltip"
154165
@pointerdown="hideTooltip"
@@ -170,7 +181,8 @@ const moreButtonActive = computed(() => selectedInOverflow.value || isOverflowPa
170181
ref="moreButton"
171182
aria-label="Show more"
172183
class="relative flex items-center justify-center w-8 h-8 rounded-lg transition mt-auto flex-none"
173-
:class="moreButtonActive ? 'text-primary bg-active' : 'op60 hover:op100 hover:bg-active'"
184+
:class="moreButtonActive ? (group.accentColor ? '' : 'text-primary bg-active') : 'op60 hover:op100 hover:bg-active'"
185+
:style="moreButtonStyle"
174186
@pointerenter="showTooltip($event, 'Show more')"
175187
@pointerleave="hideTooltip"
176188
@pointerdown="hideTooltip"
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Inline `:style` helpers for `DevframeViewGroup.accentColor` — an optional,
3+
* arbitrary CSS color set by the group's owner. Since the value isn't known
4+
* at build time it can't become a UnoCSS utility class (mirrors the
5+
* `getHashColorFromString` → `HashBadge` pattern), so callers bind these as
6+
* `:style` and keep their default Uno classes (e.g. `text-primary`,
7+
* `bg-active`) as the fallback for when `accentColor` is unset — per the
8+
* field's own doc comment.
9+
*/
10+
11+
/** Text color only — for the group button / anchor icon. */
12+
export function accentTextStyle(color: string | undefined): { color: string } | undefined {
13+
return color ? { color } : undefined
14+
}
15+
16+
/** Text color plus a soft tinted background — for an active/selected row. */
17+
export function accentActiveStyle(color: string | undefined): { color: string, backgroundColor: string } | undefined {
18+
if (!color)
19+
return undefined
20+
return {
21+
color,
22+
backgroundColor: `color-mix(in srgb, ${color} 15%, transparent)`,
23+
}
24+
}

0 commit comments

Comments
 (0)