new navbar component - #725
Conversation
…@3.1.3-13 pane-registry@3.1.2-2 activitystreams-pane@1.0.3-4 chat-pane@3.0.4-3 contacts-pane@3.2.1-5 folder-pane@3.1.1-2 issue-pane@3.0.3-1 meeting-pane@3.0.3-1 profile-pane@3.2.3-4 source-pane@3.1.1-5) (latest: rdflib@2.4.0)
There was a problem hiding this comment.
Pull request overview
This PR introduces a new solid-panes-navbar web component and wires it into the main page flow, while also refactoring some outline/pod-storage logic and adjusting build/watch behavior in Vite.
Changes:
- Add a new Navbar web component (
solid-panes-navbar) plus main-page creation/insert logic. - Refactor pod storage discovery and folder-pane item creation into new outline utilities, and update outline manager behavior/UI.
- Update Vite config to speed up
vite build --watchand ensure async/nested plugins (incl. babel) are preserved; bump package version and update lockfile.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| vite.config.mts | Adds watch-mode optimizations and async plugin flattening for reliable builds. |
| src/social/socialPane.css | Tweaks spacing and removes redundant .social-pane block. |
| src/registerPanes.js | Changes pane registration (notably default/internal panes). |
| src/outline/podUtils.ts | New helper for discovering pod storage containers + loading container turtle. |
| src/outline/folderPaneUtils.ts | New helper for producing folder-pane menu items for pod storages. |
| src/outline/manager.js | Integrates new pod/folder helpers; adjusts navbar visibility; removes parts of icon-tray logic. |
| src/outline/manager.css | Updates .tdFlex styling used by outline header row. |
| src/mainPage/navbar.ts | Creates and inserts the new navbar component; builds menu items. |
| src/mainPage/index.ts | Initializes navbar alongside the existing header. |
| src/components/navbar/Navbar.ts | Implements the solid-panes-navbar component. |
| src/components/navbar/Navbar.styles.css | Adds navbar/button styles (nested under :host). |
| src/components/navbar/index.ts | Exports the Navbar component module. |
| package.json | Version bump and removal of dependency overrides. |
| package-lock.json | Lockfile updates including nested dependency installs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import '~icons/lucide/folder-open' | ||
| import '../components/navbar' | ||
| import { NamedNode } from 'rdflib' | ||
| import { NavbarMenuItem } from 'src/components/navbar/Navbar' |
| createNavItem('Storage', () => { | ||
| const folderPanes = podStorages.map((pod, index) => createFolderPaneItem(outliner?.context?.session?.paneRegistry?.byName('folder'), pod, index)) | ||
| if (folderPanes.length === 0) { | ||
| console.warn('Folder pane is not registered') | ||
| return | ||
| } | ||
| // TODO make storage work for more storage spaces, not just the first one | ||
| outliner.GotoSubject(subject, true, folderPanes[0], true, undefined, OutlineView) | ||
| }) |
| const currentUrl = new URL(document.location.href) | ||
| const targetUrl = new URL(subject.uri, document.location.href) | ||
| console.log('currentUrl.origin: ' + currentUrl) | ||
| console.log('targetUrl.origin: ' + targetUrl) | ||
| if (currentUrl.origin === targetUrl.origin) { |
| return [panes.byName('internal')] | ||
| } | ||
|
|
||
| // filter according to audience (develoepr and or power user) |
| <button | ||
| type='button' | ||
| @click=${() => menuItem.onSelected?.()} | ||
| title="${menuItem.label}" | ||
| text="${menuItem.label}" | ||
| aria-expanded="false"> | ||
| ${menuItem.label} |
| register(tableViewPane) | ||
|
|
||
| // Fallback totally generic: | ||
| register(defaultPane) | ||
| // register(defaultPane) | ||
|
|
| register(sharingPane) | ||
|
|
||
| // The internals pane is always (almost?) the last as it is the least user-friendly | ||
| register(internalPane) | ||
| // register(internalPane) // under the hood has been removed with new design | ||
|
|
| "pane-registry": "3.1.2-2", | ||
| "profile-pane": "3.2.3-3", | ||
| "rdflib": "2.4.0", | ||
| "solid-logic": "4.0.8-1", | ||
| "solid-namespace": "^0.5.4", | ||
| "solid-ui": "3.1.3-13", | ||
| "source-pane": "3.1.1-4" | ||
| }, | ||
| "overrides": { | ||
| "rdflib": "$rdflib", | ||
| "solid-logic": "$solid-logic", | ||
| "solid-ui": "$solid-ui", | ||
| "pane-registry": "$pane-registry" | ||
| }, | ||
| "devDependencies": { |
| return html` | ||
| <nav class="navbar"> | ||
| ${this.navbarItems.map(menuItem => html` | ||
| <button |
There was a problem hiding this comment.
I have a feeling you are planning to use them later, but just in case you have not used
solid-ui-button or the menu etc..
Also, just a note that I'm going to need to add configuration to the menu-item so that the size of the icon and font can be changed in order to use it for the 3 dot menu. Perhaps you'll need this too.
| createNavItem('Storage', () => { | ||
| const folderPanes = podStorages.map((pod, index) => createFolderPaneItem(outliner?.context?.session?.paneRegistry?.byName('folder'), pod, index)) | ||
| if (folderPanes.length === 0) { | ||
| console.warn('Folder pane is not registered') |
There was a problem hiding this comment.
maybe you should also add this message for profile and social.
| return document.querySelector('solid-panes-navbar') | ||
| } | ||
|
|
||
| function hideSolidPanesNavbar () { |
There was a problem hiding this comment.
we could use classes instead of inline styles to toggle. Maybe you were going to add that later.
| const relevantPanes = panes.list.filter( | ||
| pane => pane.label(subject, context) && !pane.global | ||
| ) | ||
| if (relevantPanes.length === 0) { |
There was a problem hiding this comment.
if there are no relevant panes now what will get shown instead? The folder-pane may need this, I can't be sure yet though just a note to check.
| } | ||
|
|
||
| async function expandedHeaderTR (subject, requiredPane, options) { | ||
| async function determineFirstPane (options = {}) { |
There was a problem hiding this comment.
I see perhaps it's here, why we don't need the relevant pane ... return 'internal'?
| } | ||
|
|
||
| async function renderPaneIconTray (td, options = {}) { | ||
| // Icon tray removed: this UI is no longer needed. |
There was a problem hiding this comment.
I'm thinking that this will basically be in that 3 dots menu (at least source pane, maybe others). so anything that was shown here can be accessed still.
| }) | ||
| ) | ||
| // Pane icon tray removed: preserve first-pane selection without rendering the tray. | ||
| await determineFirstPane({ hideList: showHeader }) |
There was a problem hiding this comment.
I'm just making a note here, because I need to recheck this.
I want to check is this only the tray... because I believe the header also has the file name for instance and I'm going to need to move the tray, so we should technically still have the header but instead of the icon tray they will just be menu items in the 3 dots.
Basically I think it should still be shown, definitely for a pod "owner" (logged in, looking at your own profile). I'm not sure about the other 2 viewerModes I need to recheck the design.
i'm kind of thinking that we need the viewerMode that is in profile-pane to be at a higher level here in solid-panes.
There was a problem hiding this comment.
I brought down your code and see that the file name is still there and a few icons like the pane it is, source, and sharing. this is good. so I can just move them to the 3 dots in a different PR that should work, the header is still there. Interestingly, and I haven't gone through the manager code yet in detail but this change you made did not effect the containers.
Also, (I am just making notes for consideration). In the new design the containers are instead shown in a square div with the 3 dots at the corner.
| outlineRefocus(p, subject, pane) | ||
| } else { | ||
| if (e.altKey) { | ||
| /* if (e.altKey) { |
There was a problem hiding this comment.
If internal is no longer our default, do we have/need a default?
| showSolidPanesNavbar() | ||
| } | ||
|
|
||
| table = table || outlineContainer // if does not exist create a compatible host in the current shell |
There was a problem hiding this comment.
you probably had to do it for some reason, but funny to move this below the check. Seems like it shoudl stay above it.
|
|
||
| // Fallback totally generic: | ||
| register(defaultPane) | ||
| // register(defaultPane) |
There was a problem hiding this comment.
this is really interesting. it's actually a Developer only pane, it's the one that says "about".
why would it say for instance fallback totally generic when it could only be shown for someone who has Developer as their user preference.
I think we should discuss what it does today and if we still want it for people who have Developer selected.

|
|
||
| // The internals pane is always (almost?) the last as it is the least user-friendly | ||
| register(internalPane) | ||
| // register(internalPane) // under the hood has been removed with new design |
There was a problem hiding this comment.
| "source-pane": "3.1.1-4" | ||
| }, | ||
| "overrides": { | ||
| "rdflib": "$rdflib", |
There was a problem hiding this comment.
Because rdflib is not in my solidos setup I didn't have to remove this one. Thought I'd just mention.


This creates a new Navbar web component.
I removed the top icon tray nav but kept it for the resources in the file explorer for now.