diff --git a/components/page/demo/page-component.js b/components/page/demo/page-component.js index 8dd0d2dd1bd..f166aee82ff 100644 --- a/components/page/demo/page-component.js +++ b/components/page/demo/page-component.js @@ -60,6 +60,7 @@ class PageDemo extends LitElement { } .horizontal-fields { display: flex; + flex-wrap: wrap; gap: 1rem; } `]; diff --git a/components/page/page-divider-internal.js b/components/page/page-divider-internal.js index d2466c50cb0..1d28d251dab 100644 --- a/components/page/page-divider-internal.js +++ b/components/page/page-divider-internal.js @@ -57,16 +57,22 @@ class PageDivider extends FocusMixin(PropertyRequiredMixin(LitElement)) { background-color: var(--d2l-color-gypsum); cursor: ew-resize; height: 100%; - outline: none; + position: relative; width: ${DIVIDER_WIDTH}px; } .divider:hover { background-color: var(--d2l-color-mica); } - .divider:focus { + .divider:focus-within { background-color: var(--d2l-color-celestine); } + .slider { + outline: none; + position: absolute; + top: 55px; + } + :host([panel-type="drawer"]) .divider { background-color: var(--d2l-color-celestine); cursor: ns-resize; @@ -74,11 +80,16 @@ class PageDivider extends FocusMixin(PropertyRequiredMixin(LitElement)) { width: 100%; } + :host([panel-type="drawer"]) .slider { + inset-inline-end: 18px; + top: auto; + } + /* TO DO: Lots more divider styling to come */ `; - static focusElementSelector = '.divider'; + static focusElementSelector = '.slider'; constructor() { super(); @@ -98,17 +109,19 @@ class PageDivider extends FocusMixin(PropertyRequiredMixin(LitElement)) { } return html` -
+
+
+
`; } @@ -148,6 +161,11 @@ class PageDivider extends FocusMixin(PropertyRequiredMixin(LitElement)) { this.#sendResizeEvent(requestedSize); } + #handlePointerDown(e) { + e.preventDefault(); + this.focus(); + } + #sendResizeEvent(requestedSize) { const clampedRequestedSize = clampedSize(requestedSize, this.minSize, this.maxSize); /** @ignore */ diff --git a/components/page/page.js b/components/page/page.js index 8ad02253eec..6791db83bb1 100644 --- a/components/page/page.js +++ b/components/page/page.js @@ -132,13 +132,18 @@ class Page extends ProviderMixin(LocalizeCoreElement(LitElement)) { } .side-nav-panel, - .supporting-panel { + .supporting-panel, + .divider { max-height: calc(100vh - var(--d2l-page-header-height, 0) - var(--d2l-page-footer-height, 0)); - overflow: clip auto; position: sticky; top: var(--d2l-page-header-height, 0); } + .side-nav-panel, + .supporting-panel { + overflow: clip auto; + } + .footer:not([hidden]), .floating-buttons-container { display: inline; @@ -294,6 +299,7 @@ class Page extends ProviderMixin(LocalizeCoreElement(LitElement)) { #renderDivider(panelKey, label, panelPosition) { return html` { @@ -11,7 +11,7 @@ describe('d2l-page-divider-internal', () => { describe('accessibility', () => { it('calculates aria values correctly', async() => { const elem = await fixture(html``); - const slider = elem.shadowRoot.querySelector('.divider'); + const slider = getSlider(elem); expect(slider.getAttribute('aria-valuemax')).to.equal('200'); expect(slider.getAttribute('aria-valuemin')).to.equal('0'); expect(slider.getAttribute('aria-valuenow')).to.equal('150'); @@ -20,7 +20,7 @@ describe('d2l-page-divider-internal', () => { it('does not set aria values when in unknown state', async() => { const elem = await fixture(html``); - const slider = elem.shadowRoot.querySelector('.divider'); + const slider = getSlider(elem); expect(slider.hasAttribute('aria-valuemax')).to.be.false; expect(slider.hasAttribute('aria-valuemin')).to.be.false; expect(slider.hasAttribute('aria-valuenow')).to.be.false; diff --git a/components/page/test/page-divider-internal.vdiff.js b/components/page/test/page-divider-internal.vdiff.js index 8268d3f1dcb..908a556ca78 100644 --- a/components/page/test/page-divider-internal.vdiff.js +++ b/components/page/test/page-divider-internal.vdiff.js @@ -51,6 +51,24 @@ describe('page-divider-internal', () => { }); }); + describe('focus-stay-scrolled', () => { + [ + { name: 'main', divider: 'side-nav', fixture: pageDividerFixtures.sideNavLongMainBothHeaders }, + { name: 'panel', divider: 'supporting', fixture: pageDividerFixtures.supportingLongFooter }, + { name: 'immersive-main', divider: 'supporting', fixture: pageDividerFixtures.supportingImmersiveLongMain }, + { name: 'immersive-panel', divider: 'side-nav', fixture: pageDividerFixtures.sideNavImmersiveLongFooter } + ].forEach(test => { + it(test.name, async() => { + const elem = await fixture(test.fixture, { pagePadding: false, viewport: { width: 1000, height: 400 } }); + window.scrollTo(0, document.body.scrollHeight); + const panel = elem.shadowRoot.querySelector(`.${test.divider}-panel`); + panel.scrollTop = panel.scrollHeight; + await focusElem(getDivider(elem, test.divider)); + await expect(elem).to.be.golden({ margin: 0 }); + }); + }); + }); + describe('keyboard', () => { // TO DO once arrow visuals added });