From 433ca98e499fb86c2e9701cca7d767b6e11e59df Mon Sep 17 00:00:00 2001 From: jonahtanjz Date: Sat, 6 Feb 2021 22:11:58 +0800 Subject: [PATCH 1/2] Make css with header height reactive When header size is changed, the respective css rules that depend on the height of the header remain the same. Let's modify the css rules to change according to the size of the header. --- packages/core-web/src/index.js | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/packages/core-web/src/index.js b/packages/core-web/src/index.js index 6ca1b68a80..fd142a3fd4 100644 --- a/packages/core-web/src/index.js +++ b/packages/core-web/src/index.js @@ -50,6 +50,40 @@ function detectAndApplyFixedHeaderStyles() { margin-top: calc(-${headerHeight}px - ${bufferHeight}rem); height: calc(${headerHeight}px + ${bufferHeight}rem); }`); + insertCss(`.nav-menu-open { max-height: calc(100% - ${headerHeight}px); }`); + + const addResizeHeaderListener = () => { + const resizeObserver = new ResizeObserver(() => { + const newHeaderHeight = headerSelector.height(); + const sheets = document.styleSheets; + for (let i = 0; i < sheets.length; i += 1) { + const rules = sheets[i].cssRules; + // eslint-disable-next-line lodash/prefer-get + if (rules && rules[0] && rules[0].selectorText) { + switch (rules[0].selectorText) { + case '.fixed-header-padding': + sheets[i].deleteRule(0); + sheets[i].insertRule(`.fixed-header-padding { padding-top: ${newHeaderHeight}px !important }`); + break; + case 'span.anchor': + rules[0].style.top = `calc(-${newHeaderHeight}px - ${bufferHeight}rem)`; + break; + case 'span.card-container::before': + rules[0].style.marginTop = `calc(-${newHeaderHeight}px - ${bufferHeight}rem)`; + rules[0].style.height = `calc(${newHeaderHeight}px + ${bufferHeight}rem)`; + break; + case '.nav-menu-open': + rules[0].style.maxHeight = `calc(100% - ${newHeaderHeight}px + 50px)`; + break; + default: + break; + } + } + } + }); + resizeObserver.observe(headerSelector[0]); + }; + addResizeHeaderListener(); } function updateSearchData(vm) { From 732c39d4446378885d410d47a3ece6664832ecb1 Mon Sep 17 00:00:00 2001 From: jonahtanjz Date: Sat, 6 Feb 2021 22:13:00 +0800 Subject: [PATCH 2/2] Implement mobile site and page navigation menus --- docs/userGuide/syntax/navBars.mbdf | 23 ++ .../userGuide/syntax/pageNavigationMenus.mbdf | 2 + .../userGuide/syntax/siteNavigationMenus.mbdf | 1 + packages/core-web/src/styles/markbind.css | 2 +- packages/vue-components/src/Navbar.vue | 81 +++-- packages/vue-components/src/Overlay.vue | 109 +++++++ packages/vue-components/src/PageNavButton.vue | 77 +++++ packages/vue-components/src/SiteNavButton.vue | 68 ++++ .../src/__tests__/Navbar.spec.js | 87 +++++ .../__snapshots__/Navbar.spec.js.snap | 303 ++++++++++++++++++ packages/vue-components/src/index.js | 6 + packages/vue-components/src/utils/pubsub.js | 15 + 12 files changed, 749 insertions(+), 25 deletions(-) create mode 100644 packages/vue-components/src/Overlay.vue create mode 100644 packages/vue-components/src/PageNavButton.vue create mode 100644 packages/vue-components/src/SiteNavButton.vue create mode 100644 packages/vue-components/src/__tests__/Navbar.spec.js create mode 100644 packages/vue-components/src/__tests__/__snapshots__/Navbar.spec.js.snap create mode 100644 packages/vue-components/src/utils/pubsub.js diff --git a/docs/userGuide/syntax/navBars.mbdf b/docs/userGuide/syntax/navBars.mbdf index 5707b0c9fb..7ff40fa4f6 100644 --- a/docs/userGuide/syntax/navBars.mbdf +++ b/docs/userGuide/syntax/navBars.mbdf @@ -158,3 +158,26 @@ Name | Description + +****Page and site navigation menus**** +Both [site navigation]({{ baseUrl }}/userGuide/usingComponents.html#site-navigation-menus) and [page navigation]({{ baseUrl }}/userGuide/usingComponents.html#page-navigation-menus) menus will be hidden on smaller screens. +To make these accessible on smaller screens, you can use the `` and `` components in the `lower-navbar` slot. By default, if the `lower-navbar` slot is not specified, both the site and +page navigation buttons will automatically be added if they exist. + +```html{.no-line-numbers} + + + MarkBind +
  • Highlighted Link
  • + + +
    +``` + +Component | Description +--- | --- +`page-nav-button` | Pulls any element with an identifier, `id=page-nav` into the menu. If no such element exists, it pulls any [page navigation menu]({{ baseUrl }}/userGuide/usingComponents.html#page-navigation-menus) used in the layout. +`site-nav-button` | Pulls any element with an identifier, `id=site-nav` into the menu. If no such element exists, it pulls the first [site navigation menu]({{ baseUrl }}/userGuide/usingComponents.html#site-navigation-menus) used in the layout. \ No newline at end of file diff --git a/docs/userGuide/syntax/pageNavigationMenus.mbdf b/docs/userGuide/syntax/pageNavigationMenus.mbdf index a650164193..935460605f 100644 --- a/docs/userGuide/syntax/pageNavigationMenus.mbdf +++ b/docs/userGuide/syntax/pageNavigationMenus.mbdf @@ -17,6 +17,8 @@ 3. **Position the page navigation menu** within your layout using the `{% raw %}{{ pageNav }}{% endraw %}` variable. +4. **(Optional) To make pageNav accessible on smaller screens, you can use the `` component in the [navbar]({{baseUrl}}/userGuide/usingComponents.html#navbars).** +
    {{ icon_example }} diff --git a/docs/userGuide/syntax/siteNavigationMenus.mbdf b/docs/userGuide/syntax/siteNavigationMenus.mbdf index c5c501cf3e..9bb93ddb3c 100644 --- a/docs/userGuide/syntax/siteNavigationMenus.mbdf +++ b/docs/userGuide/syntax/siteNavigationMenus.mbdf @@ -7,6 +7,7 @@ Steps to add a siteNav: 1. Format your siteNav as an unordered Markdown list 2. Include it under a `` element. +3. (Optional) To make siteNav accessible on smaller screens, you can use the `` component in the [navbar]({{baseUrl}}/userGuide/usingComponents.html#navbars).
    diff --git a/packages/core-web/src/styles/markbind.css b/packages/core-web/src/styles/markbind.css index 172a06db93..76946594d4 100644 --- a/packages/core-web/src/styles/markbind.css +++ b/packages/core-web/src/styles/markbind.css @@ -120,7 +120,7 @@ code.hljs.inline { header[fixed] { position: fixed; width: 100%; - z-index: 1000; + z-index: 1001; } /* #app is treated as the main container */ diff --git a/packages/vue-components/src/Navbar.vue b/packages/vue-components/src/Navbar.vue index 874b5cffa1..c2be04f3a0 100644 --- a/packages/vue-components/src/Navbar.vue +++ b/packages/vue-components/src/Navbar.vue @@ -1,31 +1,39 @@ @@ -255,4 +280,12 @@ export default { color: #fff !important; background: #007bff; } + + .lower-navbar-container { + background-color: #fff; + border-bottom: 1px solid #c1c1c1; + height: 50px; + width: 100%; + position: relative; + } diff --git a/packages/vue-components/src/Overlay.vue b/packages/vue-components/src/Overlay.vue new file mode 100644 index 0000000000..84581dacea --- /dev/null +++ b/packages/vue-components/src/Overlay.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/packages/vue-components/src/PageNavButton.vue b/packages/vue-components/src/PageNavButton.vue new file mode 100644 index 0000000000..8f963c1941 --- /dev/null +++ b/packages/vue-components/src/PageNavButton.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/packages/vue-components/src/SiteNavButton.vue b/packages/vue-components/src/SiteNavButton.vue new file mode 100644 index 0000000000..d5614f81d2 --- /dev/null +++ b/packages/vue-components/src/SiteNavButton.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/packages/vue-components/src/__tests__/Navbar.spec.js b/packages/vue-components/src/__tests__/Navbar.spec.js new file mode 100644 index 0000000000..1486a7e2e3 --- /dev/null +++ b/packages/vue-components/src/__tests__/Navbar.spec.js @@ -0,0 +1,87 @@ +import { mount } from '@vue/test-utils'; +import Navbar from '../Navbar.vue'; +import PageNavButton from '../PageNavButton.vue'; +import SiteNavButton from '../SiteNavButton.vue'; + +const DEFAULT_STUBS = { + 'page-nav-button': PageNavButton, + 'site-nav-button': SiteNavButton, +}; + +const NAVBAR_CONTENT = ` +Your Logo +
  • Topic 1
  • +
  • Topic 2
  • + +`; + +const OMIT_PAGE_AND_SITE_NAV_BUTTONS = '
    '; + +const SITE_NAV_BUTTON = ` + +`; + +const PAGE_NAV_BUTTON = ` + +`; + +const SITE_AND_PAGE_NAV_BUTTONS = ` + +`; + +describe('Navbar and secondary navbar', () => { + test('navbar without site and page nav buttons', async () => { + const wrapper = mount(Navbar, { + slots: { + default: NAVBAR_CONTENT, + 'lower-navbar': OMIT_PAGE_AND_SITE_NAV_BUTTONS, + }, + stubs: DEFAULT_STUBS, + }); + + expect(wrapper.element).toMatchSnapshot(); + }); + + test('navbar with site nav button', async () => { + const wrapper = mount(Navbar, { + slots: { + default: NAVBAR_CONTENT, + 'lower-navbar': SITE_NAV_BUTTON, + }, + stubs: DEFAULT_STUBS, + }); + + expect(wrapper.element).toMatchSnapshot(); + }); + + test('navbar with page nav button', async () => { + const wrapper = mount(Navbar, { + slots: { + default: NAVBAR_CONTENT, + 'lower-navbar': PAGE_NAV_BUTTON, + }, + stubs: DEFAULT_STUBS, + }); + + expect(wrapper.element).toMatchSnapshot(); + }); + + test('navbar with site and page nav buttons', async () => { + const wrapper = mount(Navbar, { + slots: { + default: NAVBAR_CONTENT, + 'lower-navbar': SITE_AND_PAGE_NAV_BUTTONS, + }, + stubs: DEFAULT_STUBS, + }); + + expect(wrapper.element).toMatchSnapshot(); + }); +}); diff --git a/packages/vue-components/src/__tests__/__snapshots__/Navbar.spec.js.snap b/packages/vue-components/src/__tests__/__snapshots__/Navbar.spec.js.snap new file mode 100644 index 0000000000..3d723db6c4 --- /dev/null +++ b/packages/vue-components/src/__tests__/__snapshots__/Navbar.spec.js.snap @@ -0,0 +1,303 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Navbar and secondary navbar navbar with page nav button 1`] = ` +
    + + + +
    +`; + +exports[`Navbar and secondary navbar navbar with site and page nav buttons 1`] = ` +
    + + + +
    +`; + +exports[`Navbar and secondary navbar navbar with site nav button 1`] = ` +
    + + + +
    +`; + +exports[`Navbar and secondary navbar navbar without site and page nav buttons 1`] = ` +
    + + + +`; diff --git a/packages/vue-components/src/index.js b/packages/vue-components/src/index.js index 72493e927d..cba13d00d1 100644 --- a/packages/vue-components/src/index.js +++ b/packages/vue-components/src/index.js @@ -26,6 +26,9 @@ import tipBox from './TipBox.vue'; import trigger from './Trigger.vue'; import siteNav from './SiteNav.vue'; import submenu from './Submenu.vue'; +import siteNavButton from './SiteNavButton.vue'; +import pageNavButton from './PageNavButton.vue'; +import overlay from './Overlay.vue'; const components = { box: tipBox, @@ -46,6 +49,9 @@ const components = { trigger, siteNav, submenu, + siteNavButton, + pageNavButton, + overlay, }; const directives = { diff --git a/packages/vue-components/src/utils/pubsub.js b/packages/vue-components/src/utils/pubsub.js new file mode 100644 index 0000000000..9c5eb2e29d --- /dev/null +++ b/packages/vue-components/src/utils/pubsub.js @@ -0,0 +1,15 @@ +const subscribers = {}; + +export function subscribe(event, handler) { + if (!subscribers[event]) { + subscribers[event] = []; + } + subscribers[event].push(handler); +} + +export function publish(event) { + if (!subscribers[event]) { + return; + } + subscribers[event].forEach(handler => handler()); +}