GAUD-9165 - Implement the d2l-page skeleton#6904
Conversation
|
Thanks for the PR! 🎉 We've deployed an automatic preview for this PR - you can see your changes here:
Note The build needs to finish before your changes are deployed. |
| class PageDemo extends LitElement { | ||
|
|
||
| static properties = { | ||
| demoMode: { type: Boolean, attribute: 'demo-mode' }, |
There was a problem hiding this comment.
Was thinking I could also use this component for vdiff, so this is a bit heavy (being able to set controls with the switches and by a consumer, and hide the switches to look better in the vdiff. We can simplify this if that doesn't end up happening.
|
|
||
| constructor() { | ||
| super(); | ||
| this._allowThreePanels = false; // Temp for dev/testing |
There was a problem hiding this comment.
This is really handy for dev, but will go away if we aren't supporting it. Likewise, we need to decide what happens if people try to use both - throw an error? Simply hide the supporting panel? Something else?
There was a problem hiding this comment.
Made a story to come back to this question: https://desire2learn.atlassian.net/browse/GAUD-9885
|
|
||
| #renderSideNavPanel() { | ||
| return this.hasSideNavPanel ? html` | ||
| <div style="background-color: lavender; height: 1000px;" slot="side-nav"> |
There was a problem hiding this comment.
Colours here are temporary until the layout components are added and the demo is more fleshed out. Just thought it looked nice.
There was a problem hiding this comment.
This whole file will go away - once the navigation pieces are in core, we can use them directly in #renderFullNav and #renderImmersiveNav and just add a few of these extra styles in page-component directly.
Disclaimer: I told Copilot to create these navs and then I updated them to use the CSS properties that the official nav pieces will use - didn't review the other temporary styles very closely.
There was a problem hiding this comment.
Still planning the tests and vdiffs, in coordination with the layout stuff
| --d2l-page-header-max-width: 1230px; | ||
| --d2l-page-content-max-width: 1230px; | ||
| --d2l-page-footer-max-width: 1230px; | ||
| --d2l-page-margin-inline: auto; |
There was a problem hiding this comment.
This can maybe go away if we're not doing fancy nav stuff at different widths - we should revisit with the official nav stuff.
|
|
||
| main { | ||
| flex: 1; | ||
| min-width: 400px; /* TBD */ |
There was a problem hiding this comment.
Open design question on whether this should be 400px or 600px, plus this will likely all adjust as panels start opening/closing/resizing. Kinda just a placeholder for now.
There was a problem hiding this comment.
Interesting! I'll move it there for now, and then I think a lot of this logic is gonna have to be baked into the divider stuff anyways.
There was a problem hiding this comment.
Actually, just made this a bit more resilient and made the nav a bit more wrappy. I still think it'll eventually change, but it's the main panel that design specifically doesn't want sized smaller than 400px by the side panels. But then of course, if the page is smaller than that it'll need to adapt
| //this._headerIsSticky = nodes.some(node => node.tagName.toLowerCase() === 'd2l-page-header-immersive'); | ||
| this._headerIsSticky = nodes.some(node => node.id === 'immersive-nav'); // temp until the official component exists |
There was a problem hiding this comment.
Open question on how we want to do this. I figured we'd just look for the actual component name so consumers can't easily set something and work around our choice (that full nav scrolls and immersive nav sticks). But maybe we want something more generic/flexible, and we have immersive-nav sprout a data attribute that this can look for?
There was a problem hiding this comment.
My initial thought for solving this was to have the header dispatch an event with information in the detail that indicates what it would prefer. The page could also add stuff to that event detail if we needed cross-component communication.
But this also works for the time being!
There was a problem hiding this comment.
Yeah I feel like you'll naturally revisit this with immersive-nav and we can test out what works best
| #handleSlotVisibilityChange(e) { | ||
| const key = e.target.name; | ||
| const nodes = e.target.assignedNodes(); | ||
| this._slotVisibility = { ...this._slotVisibility, [key]: nodes.length !== 0 }; | ||
| this.requestUpdate(); | ||
| } |
There was a problem hiding this comment.
I did this when I was looking for like 8 slots and hiding/showing them accordingly, but now there's only three (footer, side-nav, supporting) so this might be overkill. But also, may became relevant in the d2l-page-main components (header, breadcrumbs, etc.) 🤷♀️ - thoughts?
There was a problem hiding this comment.
Yeah at first I was going to add a comment about how just having a few state properties would be easier to understand... but this is pretty elegant in terms of only needing a single slot change handler so I'm on the fence.
| } | ||
|
|
||
| #renderFloatingButtons(footerContents) { | ||
| // Floating buttons needs to be wrapped as it spawns a sibling element that should be cleaned up as one by Lit |
There was a problem hiding this comment.
This might not be an actual problem, because people shouldn't be changing their number of panels and footer type on the fly in their page like the demo page is. But it was infuriating and the lit-html error it caused was incredibly vague, and I'd like to handle it. May have also come up when handling the mobile view switching.
There was a problem hiding this comment.
Floating buttons are the (second) worst.
|
Looks like
|
Ok, I have a simple |
| main { | ||
| flex: 1; | ||
| min-width: 400px; /* TBD */ | ||
| overflow: clip; |
There was a problem hiding this comment.
Not actually sure what overflow behaviour we want - clip so there's no way for the panels to overflow onto each other, and people need to make sure their content is responsive? Scroll? Default to one of these as the host style of the d2l-page-main, d2l-page-side-nav, etc. but have it overridable?
There was a problem hiding this comment.
I'm also not sure. I think we'd want auto instead of scroll since that puts the browser in control of whether scrollbars are visible.
My vote would be to leave it unset for main but clip auto for the nav/supporting.
There was a problem hiding this comment.
This will make things overflow for now, until we add the padding, because a lot of our components expand outside their bounds for hover styles
| #handleAllowThreePanelsChange(e) { | ||
| this._allowThreePanels = e.target.on; | ||
| if (!this._allowThreePanels && this.hasSideNavPanel && this.hasSupportingPanel) { | ||
| this.shadowRoot.querySelector('#switch-supporting-panel').on = false; |
There was a problem hiding this comment.
This violates render() being a function of the properties. Setting this._allowThreePanels should trigger a re-render anyway -- can the on boolean just be calculated and set from there?
|
|
||
| if (this._allowThreePanels) return; | ||
| if (e.target.on && key === 'hasSideNavPanel' && this.hasSupportingPanel) { | ||
| this.shadowRoot.querySelector('#switch-supporting-panel').on = false; |
There was a problem hiding this comment.
Similar comment here (and just below).
There was a problem hiding this comment.
Fair, I think I did it here to be able to easily mass delete it at some point, but I can try moving it right into render
| <div class="full-nav-header-right"> | ||
| <button class="nav-icon-btn" title="Alerts">🔔</button> | ||
| <button class="nav-icon-btn" title="Settings">⚙️</button> | ||
| <button class="nav-icon-btn" title="Profile">👤</button> |
There was a problem hiding this comment.
These are lovely! We should use them in the real nav. 😆
|
|
||
| #renderMainPanel() { | ||
| return html` | ||
| <div style="height: 1000px;"> |
There was a problem hiding this comment.
Looks like the height got removed in a follow-up PR, but is this <div> even needed?
There was a problem hiding this comment.
Was basically using it to test scroll and as a placeholder for the d2l-page-main, although then I added the end content piece so it's not perfect. It will be gone by the end of the PR chain 😅
| const footer = html` | ||
| <div class="${classMap(footerContainerClasses)}" ?hidden="${!this._slotVisibility['footer']}"> | ||
| ${fixedFooter ? footerContents : this.#renderFloatingButtons(footerContents)} | ||
| </div>`; |
There was a problem hiding this comment.
I'd be tempted to put all these inside #renderFooter(), #renderSupporting(), etc. as they're only going to get more complex from here. But that can also wait!
| //this._headerIsSticky = nodes.some(node => node.tagName.toLowerCase() === 'd2l-page-header-immersive'); | ||
| this._headerIsSticky = nodes.some(node => node.id === 'immersive-nav'); // temp until the official component exists |
There was a problem hiding this comment.
My initial thought for solving this was to have the header dispatch an event with information in the detail that indicates what it would prefer. The page could also add stuff to that event detail if we needed cross-component communication.
But this also works for the time being!
| #handleSlotVisibilityChange(e) { | ||
| const key = e.target.name; | ||
| const nodes = e.target.assignedNodes(); | ||
| this._slotVisibility = { ...this._slotVisibility, [key]: nodes.length !== 0 }; | ||
| this.requestUpdate(); | ||
| } |
There was a problem hiding this comment.
Yeah at first I was going to add a comment about how just having a few state properties would be easier to understand... but this is pretty elegant in terms of only needing a single slot change handler so I'm on the fence.
| } | ||
|
|
||
| #renderFloatingButtons(footerContents) { | ||
| // Floating buttons needs to be wrapped as it spawns a sibling element that should be cleaned up as one by Lit |
There was a problem hiding this comment.
Floating buttons are the (second) worst.
This reverts commit 551d5c7.
Co-authored-by: Dave Lockhart <dlockhart@users.noreply.github.com>
dlockhart
left a comment
There was a problem hiding this comment.
Obviously lots going to change, but I think this is in good enough shape to merge if you want to!
| .page.header-sticky .header { | ||
| position: sticky; | ||
| top: 0; | ||
| z-index: 15; /* To be over sticky content of our core components */ |
There was a problem hiding this comment.
This doesn't need to be 15, and the below doesn't need to be 10 - this is in the spirit of saving some room. I made a story about lowering collapsible-panel - if that is done, I think this could get down to like 7 or 8. But maybe we want a chart to keep track somewhere? It's currently something like:
- Table sticky heads = 4
- Scroll-wrapper = 5
- Table and List controls = 6
- Footer = 10 (Collapsible panels won't be sticky over the footer, unless the page is like 50px high)
- Collapsible-panel = 11 (Probably can be much lower now)
- Header = 15 (Can be lower)
- Floating buttons, popover stuff, dialog, toast alerts = 997+
(Probably not perfect, going off memory of a few days ago)
Yeah I think it's all very adjustable as we flesh out more pieces, but getting it in would be very helpful for the PR chain! |
|
🎉 This PR is included in version 3.241.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |


This adds
d2l-pagewith the discussed slots. It uses the full body scroll demonstrated in #6875. The demo page is bare bones and will be fleshed out in the next PR.Still tweaking a bit, experimenting with what we want vdiffs to look like, etc. but this should be good to go. Will add notes inline. I still want to give this one more go-through but I've been looking at it too long - will check Monday with fresh eyes.