Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,42 @@ export const Overflow: Story = {
),
}),
}

/**
* `expandGroupSidebar` on: a wider rail that shows each member's title next
* to its icon, so tools are findable without hovering for tooltips.
*/
export const Expanded: Story = {
render: () => ({
setup: () => mountWithContext(
{
entries: groupedEntries,
selectedId: 'nuxt:overview',
settings: { expandGroupSidebar: true },
},
ctx => stage(shell(h(DockGroupSidebar, {
context: ctx,
group: nuxtGroup,
selectedId: ctx.docks.selectedId,
}))),
),
}),
}

/** Expanded with overflow: the show-more row keeps its label and count. */
export const ExpandedOverflow: Story = {
render: () => ({
setup: () => mountWithContext(
{
entries: subcategorizedGroupEntries,
selectedId: 'tools:graph',
settings: { expandGroupSidebar: true },
},
ctx => stage(shell(h(DockGroupSidebar, {
context: ctx,
group: toolsGroup,
selectedId: ctx.docks.selectedId,
}), 'h-44')),
),
}),
}
47 changes: 35 additions & 12 deletions packages/hub-ui/src/client/components/dock/DockGroupSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ const RESERVED_HEIGHT = 53

const settings = useSettings(props.context)

// Expanded: a wider rail with each member's title next to its icon. Row
// heights stay the same, so the capacity math below holds in both modes.
const expanded = computed(() => settings.value.expandGroupSidebar)

// Members split by in-group sub-category so the sidebar can divide sections.
const memberGroups = computed(() => getGroupMembersGrouped(
props.context.docks.entries,
Expand Down Expand Up @@ -179,42 +183,54 @@ const moreButtonActive = computed(() => selectedInOverflow.value || isOverflowPa
so the anchor + selected members' text-primary/bg-active render accent. -->
<div
ref="sidebar"
class="devframes-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"
:class="group.accentColor ? 'devframes-accent-scope' : ''"
class="devframes-group-sidebar flex flex-col flex-none h-full border-r border-base of-y-hidden of-x-hidden select-none py1.5 gap-0.5"
:class="[
expanded ? 'w-44 px1.5 items-stretch' : 'w-12 items-center',
group.accentColor ? 'devframes-accent-scope' : '',
]"
:style="accentVarStyle(group.accentColor)"
>
<!-- Group anchor -->
<div
class="flex items-center justify-center w-8 h-8 op60"
:class="group.accentColor ? 'color-active' : ''"
class="flex items-center h-8 op60"
:class="[
expanded ? 'gap-2 px1.5' : 'justify-center w-8',
group.accentColor ? 'color-active' : '',
]"
@pointerenter="showTooltip($event, group)"
@pointerleave="hideTooltip"
>
<DockIcon :icon="group.icon" class="w-5 h-5 flex-none" />
<span v-if="expanded" class="text-sm font-medium truncate">{{ group.title }}</span>
</div>
<div class="w-8 h-px border-t border-base my0.5" />
<div class="h-px border-t border-base my0.5" :class="expanded ? 'w-full' : 'w-8'" />

<!-- Member icons, grouped by in-group sub-category -->
<template v-for="([category, members], idx) of visibleGroups" :key="category">
<!-- Sub-category divider, mirroring the group anchor separator -->
<div v-if="idx > 0 && members.length" class="w-8 h-px border-t border-base my0.5" />
<div v-if="idx > 0 && members.length" class="h-px border-t border-base my0.5" :class="expanded ? 'w-full' : 'w-8'" />
<button
v-for="member of members"
:key="member.id"
:aria-label="member.title"
:aria-current="currentId === member.id ? 'page' : undefined"
class="relative flex items-center justify-center w-8 h-8 rounded-lg transition"
:class="selectedId === member.id ? 'text-primary bg-active' : 'op60 hover:op100 hover:bg-active'"
class="relative flex items-center h-8 rounded-lg transition"
:class="[
expanded ? 'gap-2 px1.5' : 'justify-center w-8',
selectedId === member.id ? 'text-primary bg-active' : 'op60 hover:op100 hover:bg-active',
]"
@pointerenter="showTooltip($event, member)"
@pointerleave="hideTooltip"
@pointerdown="hideTooltip"
@click="select(member.id)"
@contextmenu="openContextMenu($event, member)"
>
<DockIcon :icon="member.icon" class="w-5 h-5 flex-none" />
<span v-if="expanded" class="flex-1 min-w-0 text-left text-sm truncate">{{ member.title }}</span>
<div
v-if="member.badge"
class="absolute top-0.5 right-0.5 bg-gray-6 text-white text-0.6em px-0.5 rounded-full shadow leading-none"
class="bg-gray-6 text-white text-0.6em px-0.5 rounded-full shadow leading-none"
:class="expanded ? 'flex-none' : 'absolute top-0.5 right-0.5'"
>
{{ member.badge }}
</div>
Expand All @@ -227,15 +243,22 @@ const moreButtonActive = computed(() => selectedInOverflow.value || isOverflowPa
ref="moreButton"
:aria-label="t('dock.showMore')"
:aria-current="currentInOverflow ? 'true' : undefined"
class="relative flex items-center justify-center w-8 h-8 rounded-lg transition mt-auto flex-none"
:class="moreButtonActive ? 'text-primary bg-active' : 'op60 hover:op100 hover:bg-active'"
class="relative flex items-center h-8 rounded-lg transition mt-auto flex-none"
:class="[
expanded ? 'gap-2 px1.5' : 'justify-center w-8',
moreButtonActive ? 'text-primary bg-active' : 'op60 hover:op100 hover:bg-active',
]"
@pointerenter="showTooltip($event, t('dock.showMore'))"
@pointerleave="hideTooltip"
@pointerdown="hideTooltip"
@click="toggleOverflowPanel"
>
<DockIcon icon="ph:dots-three-circle-duotone" class="w-5 h-5 flex-none" />
<div class="absolute top-0.5 right-0.5 bg-gray-6 text-white text-0.6em px-0.5 rounded-full shadow leading-none">
<span v-if="expanded" class="flex-1 min-w-0 text-left text-sm truncate">{{ t('dock.showMore') }}</span>
<div
class="bg-gray-6 text-white text-0.6em px-0.5 rounded-full shadow leading-none"
:class="expanded ? 'flex-none' : 'absolute top-0.5 right-0.5'"
>
{{ overflowBadge }}
</div>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,5 +234,23 @@ function setDockMode(mode: string) {
<span class="text-xs op50">{{ t('appearance.autoCollapseHint') }}</span>
</div>
</label>

<!-- Expand group sidebar toggle -->
<label class="flex items-center gap-3 cursor-pointer group">
<button
class="w-10 h-6 rounded-full transition-colors relative shrink-0"
:class="settings.expandGroupSidebar ? 'bg-primary' : 'bg-gray/30'"
@click="settingsStore.mutate((s) => { s.expandGroupSidebar = !settings.expandGroupSidebar })"
>
<div
class="absolute top-1 w-4 h-4 rounded-full bg-white shadow transition-transform"
:class="settings.expandGroupSidebar ? 'translate-x-5' : 'translate-x-1'"
/>
</button>
<div class="flex flex-col">
<span class="text-sm">{{ t('appearance.expandSidebar') }}</span>
<span class="text-xs op50">{{ t('appearance.expandSidebarHint') }}</span>
</div>
</label>
</div>
</template>
2 changes: 2 additions & 0 deletions packages/hub-ui/src/client/i18n/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"appearance.recentDocks": "Zuletzt verwendete Tools in der Dock-Leiste",
"appearance.recentDocksHint": "Zuletzt aus einer Gruppe oder dem Überlaufmenü geöffnete Tools in der Dock-Leiste behalten (nur im Float-Modus).",
"appearance.recentDocksOff": "Aus",
"appearance.expandSidebar": "Gruppen-Seitenleiste erweitern",
"appearance.expandSidebarHint": "Zeigt in der Gruppen-Seitenleiste die Namen der Tools neben ihren Symbolen.",

"docks.intro": "Sichtbarkeit und Reihenfolge der Dock-Einträge verwalten. Ausgeblendete Einträge erscheinen nicht in der Dock-Leiste.",
"docks.resetOrder": "Eigene Reihenfolge zurücksetzen",
Expand Down
2 changes: 2 additions & 0 deletions packages/hub-ui/src/client/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"appearance.recentDocks": "Recent tools on the dock bar",
"appearance.recentDocksHint": "Keep the tools you last opened from a group or the overflow menu on the dock bar (float mode only).",
"appearance.recentDocksOff": "Off",
"appearance.expandSidebar": "Expand group sidebar",
"appearance.expandSidebarHint": "Show tool names next to their icons in the group sidebar.",

"docks.intro": "Manage visibility and order of dock entries. Hidden entries will not appear in the dock bar.",
"docks.resetOrder": "Reset custom order",
Expand Down
2 changes: 2 additions & 0 deletions packages/hub-ui/src/client/i18n/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"appearance.recentDocks": "Herramientas recientes en la barra",
"appearance.recentDocksHint": "Mantén en la barra las herramientas que abriste por última vez desde un grupo o el menú de desbordamiento (solo en modo flotante).",
"appearance.recentDocksOff": "Desactivado",
"appearance.expandSidebar": "Expandir la barra lateral del grupo",
"appearance.expandSidebarHint": "Muestra el nombre de cada herramienta junto a su icono en la barra lateral del grupo.",

"docks.intro": "Gestiona la visibilidad y el orden de los paneles. Los paneles ocultos no aparecerán en la barra.",
"docks.resetOrder": "Restablecer orden personalizado",
Expand Down
2 changes: 2 additions & 0 deletions packages/hub-ui/src/client/i18n/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"appearance.recentDocks": "Outils récents dans la barre",
"appearance.recentDocksHint": "Garder dans la barre les derniers outils ouverts depuis un groupe ou le menu de débordement (mode flottant uniquement).",
"appearance.recentDocksOff": "Désactivé",
"appearance.expandSidebar": "Développer la barre latérale du groupe",
"appearance.expandSidebarHint": "Affiche le nom des outils à côté de leur icône dans la barre latérale du groupe.",

"docks.intro": "Gérez la visibilité et l'ordre des panneaux. Les panneaux masqués n'apparaissent pas dans la barre.",
"docks.resetOrder": "Réinitialiser l'ordre personnalisé",
Expand Down
2 changes: 2 additions & 0 deletions packages/hub-ui/src/client/i18n/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"appearance.recentDocks": "ドックバーの最近使ったツール",
"appearance.recentDocksHint": "グループやオーバーフローメニューから最後に開いたツールをドックバーに表示します(フロートモードのみ)。",
"appearance.recentDocksOff": "オフ",
"appearance.expandSidebar": "グループサイドバーを展開",
"appearance.expandSidebarHint": "グループサイドバーでアイコンの横にツール名を表示します。",

"docks.intro": "ドック項目の表示と順序を管理します。非表示の項目はドックバーに表示されません。",
"docks.resetOrder": "カスタム順序をリセット",
Expand Down
2 changes: 2 additions & 0 deletions packages/hub-ui/src/client/i18n/locales/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"appearance.recentDocks": "도크 바의 최근 도구",
"appearance.recentDocksHint": "그룹이나 오버플로 메뉴에서 마지막으로 연 도구를 도크 바에 유지합니다 (플로트 모드 전용).",
"appearance.recentDocksOff": "끄기",
"appearance.expandSidebar": "그룹 사이드바 펼치기",
"appearance.expandSidebarHint": "그룹 사이드바에서 아이콘 옆에 도구 이름을 표시합니다.",

"docks.intro": "도크 항목의 표시 여부와 순서를 관리합니다. 숨긴 항목은 도크 바에 나타나지 않습니다.",
"docks.resetOrder": "사용자 지정 순서 초기화",
Expand Down
2 changes: 2 additions & 0 deletions packages/hub-ui/src/client/i18n/locales/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"appearance.recentDocks": "Ferramentas recentes na barra",
"appearance.recentDocksHint": "Manter na barra as ferramentas abertas por último a partir de um grupo ou do menu de excedentes (somente no modo flutuante).",
"appearance.recentDocksOff": "Desativado",
"appearance.expandSidebar": "Expandir a barra lateral do grupo",
"appearance.expandSidebarHint": "Mostra o nome de cada ferramenta ao lado do ícone na barra lateral do grupo.",

"docks.intro": "Gerencie a visibilidade e a ordem dos painéis. Painéis ocultos não aparecem na barra.",
"docks.resetOrder": "Redefinir ordem personalizada",
Expand Down
2 changes: 2 additions & 0 deletions packages/hub-ui/src/client/i18n/locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"appearance.recentDocks": "Недавние инструменты на панели",
"appearance.recentDocksHint": "Оставлять на панели инструменты, недавно открытые из группы или меню переполнения (только в плавающем режиме).",
"appearance.recentDocksOff": "Выкл.",
"appearance.expandSidebar": "Развернуть боковую панель группы",
"appearance.expandSidebarHint": "Показывать названия инструментов рядом со значками на боковой панели группы.",

"docks.intro": "Управляйте видимостью и порядком панелей. Скрытые панели не отображаются на панели инструментов.",
"docks.resetOrder": "Сбросить пользовательский порядок",
Expand Down
2 changes: 2 additions & 0 deletions packages/hub-ui/src/client/i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"appearance.recentDocks": "停靠栏中的最近工具",
"appearance.recentDocksHint": "在停靠栏中保留最近从分组或溢出菜单打开的工具(仅浮动模式)。",
"appearance.recentDocksOff": "关闭",
"appearance.expandSidebar": "展开分组侧边栏",
"appearance.expandSidebarHint": "在分组侧边栏中,于图标旁显示工具名称。",

"docks.intro": "管理工具面板条目的可见性和顺序。隐藏的条目不会出现在工具栏中。",
"docks.resetOrder": "重置自定义顺序",
Expand Down
2 changes: 2 additions & 0 deletions packages/hub-ui/src/client/i18n/locales/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"appearance.recentDocks": "停靠列中的最近工具",
"appearance.recentDocksHint": "在停靠列中保留最近從群組或溢出選單開啟的工具(僅限浮動模式)。",
"appearance.recentDocksOff": "關閉",
"appearance.expandSidebar": "展開群組側邊欄",
"appearance.expandSidebarHint": "在群組側邊欄中,於圖示旁顯示工具名稱。",

"docks.intro": "管理工具面板項目的可見性和順序。隱藏的項目不會出現在工具列中。",
"docks.resetOrder": "重設自訂順序",
Expand Down
4 changes: 3 additions & 1 deletion packages/hub-ui/src/client/state/settings-defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import '../types'
/** The subset of {@link DevframeDocksUserSettings} hub-ui itself contributes. */
export type HubUiSettings = Pick<
DevframeDocksUserSettings,
'showIframeAddressBar' | 'closeOnOutsideClick' | 'autoCollapseEdgeToolbar' | 'showDevframeInspector' | 'docksRecentLimit'
'showIframeAddressBar' | 'closeOnOutsideClick' | 'autoCollapseEdgeToolbar' | 'showDevframeInspector' | 'docksRecentLimit' | 'expandGroupSidebar'
>

/**
Expand Down Expand Up @@ -41,6 +41,8 @@ const HUB_UI_SETTINGS_DEFAULTS: Required<HubUiSettings> = Object.freeze({
showDevframeInspector: false,
/** The float bar keeps the last three docks opened from beyond it. */
docksRecentLimit: 3,
/** The group sidebar stays an icon-only rail. */
expandGroupSidebar: false,
})

/**
Expand Down
5 changes: 5 additions & 0 deletions packages/hub-ui/src/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ declare module '@devframes/hub/types' {
* off.
*/
docksRecentLimit?: number
/**
* Widen the group sidebar so each member shows its title next to its
* icon, instead of an icon-only rail with hover tooltips.
*/
expandGroupSidebar?: boolean
}
}

Expand Down
Loading