Skip to content

Commit 85a552f

Browse files
committed
building left side menu with getDashboardItems
1 parent 554c862 commit 85a552f

4 files changed

Lines changed: 112 additions & 53 deletions

File tree

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,9 @@ label: element.label,
9999
onclick: () => openDashboardPane(outliner, element.tabName || element.paneName)
100100
}
101101
})
102-
}
102+
}
103+
104+
* Auto: each #sym:MenuItem has an icon which i want displayed on the left side of each menu item when rendered
105+
106+
* Auto: don't add each menu item in a button looking border. Simply list them.
107+
Upon hover apply background color e6dcff and selected or active to be background color: cbb9ff

src/mainPage/menu.css

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,40 @@
55
}
66

77
.menu-item {
8-
display: block;
9-
border: 1px solid var(--color-border);
10-
border-radius: 0.35rem;
8+
display: flex;
9+
align-items: center;
10+
gap: 0.625rem;
11+
border: 0;
12+
border-radius: 0;
1113
padding: 0.5rem 0.75rem;
12-
background: var(--color-background);
14+
background: transparent;
1315
color: var(--color-text);
1416
text-decoration: none;
1517
width: 100%;
1618
text-align: left;
1719
cursor: pointer;
1820
}
1921

22+
.menu-item-icon {
23+
width: 1rem;
24+
height: 1rem;
25+
flex: 0 0 1rem;
26+
object-fit: contain;
27+
}
28+
29+
.menu-item-label {
30+
min-width: 0;
31+
}
32+
2033
.menu-item:hover,
2134
.menu-item:focus {
22-
background: var(--color-highlight-bg);
35+
background: #e6dcff;
36+
}
37+
38+
.menu-item-active,
39+
.menu-item-active:hover,
40+
.menu-item-active:focus {
41+
background: #cbb9ff;
2342
}
2443

2544
.menu-toggle {

src/mainPage/menu.ts

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import './menu.css'
22
import { OutlineManager } from '../outline/manager'
3-
import { authSession, authn } from 'solid-logic'
3+
import { authSession } from 'solid-logic'
44

55
type MenuItem = {
66
id?: string
7+
icon?: string
8+
paneName?: string
79
label: string
810
onclick: () => void | Promise<void>
911
}
@@ -57,6 +59,8 @@ const getMenuItems = async (outliner: any): Promise<MenuItem[]> => {
5759
const items = await outliner.getDashboardItems()
5860
return items.map((element) => {
5961
return {
62+
icon: element.icon,
63+
paneName: element.tabName || element.paneName,
6064
label: element.label,
6165
onclick: () => openDashboardPane(outliner, element.tabName || element.paneName)
6266
}
@@ -71,7 +75,23 @@ const createMenuButton = (item: MenuItem) => {
7175
const button = document.createElement('button')
7276
button.className = 'menu-item'
7377
button.type = 'button'
74-
button.textContent = item.label
78+
if (item.paneName) {
79+
button.dataset.paneName = item.paneName
80+
}
81+
82+
if (item.icon) {
83+
const icon = document.createElement('img')
84+
icon.className = 'menu-item-icon'
85+
icon.src = item.icon
86+
icon.alt = ''
87+
icon.setAttribute('aria-hidden', 'true')
88+
button.appendChild(icon)
89+
}
90+
91+
const label = document.createElement('span')
92+
label.className = 'menu-item-label'
93+
label.textContent = item.label
94+
button.appendChild(label)
7595

7696
if (item.id) {
7797
button.id = item.id
@@ -84,21 +104,38 @@ const createMenuButton = (item: MenuItem) => {
84104
return button
85105
}
86106

87-
const renderMenuItems = async (outliner: OutlineManager, container: HTMLElement) => {
88-
const me = authn.currentUser()
89-
const menuItems = me ? await getMenuItems(outliner) : []
90-
91-
if (me) {
92-
menuItems.push({
93-
id: 'MenuLogoutItem',
94-
label: 'Logout',
95-
onclick: async () => {
96-
await authSession.logout()
97-
}
98-
})
107+
const setActiveMenuItem = (container: HTMLElement, paneName?: string) => {
108+
const menuItems = Array.from(container.querySelectorAll<HTMLButtonElement>('.menu-item'))
109+
let activeItem: HTMLButtonElement | undefined
110+
111+
menuItems.forEach((item) => {
112+
const isActive = Boolean(paneName) && item.dataset.paneName === paneName
113+
item.classList.toggle('menu-item-active', isActive)
114+
if (isActive) {
115+
item.setAttribute('aria-current', 'page')
116+
activeItem = item
117+
} else {
118+
item.removeAttribute('aria-current')
119+
}
120+
})
121+
122+
if (!activeItem && menuItems[0]) {
123+
menuItems[0].classList.add('menu-item-active')
124+
menuItems[0].setAttribute('aria-current', 'page')
125+
container.dataset.activePaneName = menuItems[0].dataset.paneName || ''
126+
return
127+
}
128+
129+
if (paneName) {
130+
container.dataset.activePaneName = paneName
99131
}
132+
}
133+
134+
const renderMenuItems = async (outliner: OutlineManager, container: HTMLElement) => {
135+
const menuItems = await getMenuItems(outliner)
100136

101137
container.replaceChildren(...menuItems.map(createMenuButton))
138+
setActiveMenuItem(container, container.dataset.activePaneName)
102139
}
103140

104141
export const refreshMenu = (layout: 'mobile' | 'desktop') => {
@@ -178,6 +215,9 @@ export const createLeftSideMenu = async (outliner: OutlineManager) => {
178215

179216
navMenuContent.addEventListener('click', (event) => {
180217
const item = (event.target as HTMLElement).closest('.menu-item')
218+
if (item instanceof HTMLButtonElement) {
219+
setActiveMenuItem(navMenuContent, item.dataset.paneName)
220+
}
181221
const isMobile = outliner.context?.environment?.layout === 'mobile'
182222
if (item && isMobile) {
183223
closeMobileMenu()
@@ -187,7 +227,6 @@ export const createLeftSideMenu = async (outliner: OutlineManager) => {
187227
}
188228

189229
async function openDashboardPane (outliner: any, pane: string): Promise<void> {
190-
console.log('-----Opening profile pane')
191230
outliner.showDashboard({
192231
pane
193232
})

src/outline/manager.js

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -353,32 +353,47 @@ export default function (context) {
353353

354354
async function getDashboardItems () {
355355
const me = authn.currentUser()
356-
if (!me) return []
357-
const div = dom.createElement('div')
358-
const [pods] = await Promise.all([getPods()])
359-
return [
356+
const panes = [
360357
{
361358
paneName: 'home',
362-
label: 'Your stuff',
359+
label: 'Dashboard',
363360
icon: UI.icons.iconBase + 'noun_547570.svg'
364361
},
365-
{
366-
paneName: 'basicPreferences',
367-
label: 'Preferences',
368-
icon: UI.icons.iconBase + 'noun_Sliders_341315_00000.svg'
369-
},
370362
{
371363
paneName: 'profile',
372-
label: 'Your Profile',
364+
label: 'Profile',
373365
icon: UI.icons.iconBase + 'noun_15059.svg'
374366
},
367+
{
368+
paneName: 'socialPane',
369+
label: 'Friends',
370+
icon: UI.icons.originalIconBase + 'foaf/foafTiny.gif'
371+
}
372+
]
373+
374+
if (!me) {
375+
return panes
376+
}
377+
378+
const [pods] = await Promise.all([getPods()])
379+
panes.push(
380+
/* not in use since redesign of profile-pane
375381
{
376382
paneName: 'editProfile',
377383
label: 'Edit your Profile',
378384
icon: UI.icons.iconBase + 'noun_492246.svg'
385+
},
386+
*/
387+
{
388+
paneName: 'basicPreferences',
389+
label: 'Preferences',
390+
icon: UI.icons.iconBase + 'noun_Sliders_341315_00000.svg'
379391
}
380-
]
381-
.concat(pods)
392+
)
393+
394+
panes.push(...pods)
395+
396+
return panes
382397

383398
async function getPods () {
384399
async function addPodStorage (pod) { // namedNode
@@ -444,25 +459,6 @@ export default function (context) {
444459
}
445460
})
446461
}
447-
448-
async function getAddressBooks () {
449-
try {
450-
const context = await UI.login.findAppInstances(
451-
{ me, div, dom },
452-
ns.vcard('AddressBook')
453-
)
454-
return (context.instances || []).map((book, index) => ({
455-
paneName: 'contact',
456-
tabName: `contact-${index}`,
457-
label: 'Contacts',
458-
subject: book,
459-
icon: UI.icons.iconBase + 'noun_15695.svg'
460-
}))
461-
} catch (err) {
462-
console.error('oops in globalAppTabs AddressBook')
463-
}
464-
return []
465-
}
466462
}
467463
this.getDashboardItems = getDashboardItems
468464

0 commit comments

Comments
 (0)