From 1c8208975b5f2decd54eea7d7e25bfa342f1b1c1 Mon Sep 17 00:00:00 2001 From: Cole Goldsmith Date: Thu, 16 May 2024 18:22:14 -0500 Subject: [PATCH] Side Nav Improvements (#133) --- preview-src/ui-model.yml | 2 +- src/css/components/collapse.css | 22 ++++-------- src/css/vars/dark.css | 2 +- src/css/vars/light.css | 4 +-- src/helpers/global-nav-active.js | 38 +++++++++++++++------ src/helpers/log-pretty.js | 5 +++ src/helpers/nav-id.js | 6 ++++ src/js/01-nav.js | 10 +++--- src/js/02-on-this-page.js | 2 +- src/js/09-dropdown.js | 36 ++++++++++++++++++-- src/js/10-collapse.js | 35 ++++++++++++++++++++ src/partials/global-nav.hbs | 14 ++++---- src/partials/nav-secondary.hbs | 2 +- src/partials/nav-tree.hbs | 57 ++++++++++++++++++-------------- src/partials/nav.hbs | 5 ++- src/partials/page-versions.hbs | 6 ++-- src/partials/toc.hbs | 2 +- 17 files changed, 173 insertions(+), 75 deletions(-) create mode 100644 src/helpers/log-pretty.js create mode 100644 src/helpers/nav-id.js create mode 100644 src/js/10-collapse.js diff --git a/preview-src/ui-model.yml b/preview-src/ui-model.yml index 1a9df8dd..cf2e4c23 100644 --- a/preview-src/ui-model.yml +++ b/preview-src/ui-model.yml @@ -69,7 +69,7 @@ site: "items": [ { "title": "Apache Pulsar Connector", "url": "#" }, { "title": "CDC for Cassandra", "url": "#" }, - { "title": "K8ssandra", "url": "#" }, + { "title": "K8ssandra", "url": "https://docs.k8ssandra.io" }, { "title": "Stargate", "url": "#" }, { "title": "Starlight for JMS", "url": "#" }, { "title": "Starlight for Kafka", "url": "#" }, diff --git a/src/css/components/collapse.css b/src/css/components/collapse.css index 301201ef..c0dbedeb 100644 --- a/src/css/components/collapse.css +++ b/src/css/components/collapse.css @@ -1,13 +1,15 @@ @layer components { .collapse { - @apply !visible grid; + @apply !visible; } .collapse > .collapse-content { - @apply relative col-start-1 row-start-2 grid min-h-0; + @apply grid min-h-0 invisible; grid-template-rows: 0fr; - transition: grid-template-rows 0.2s; + transition-property: grid-template-rows, visibility; + transition-duration: 0.2s; + transition-behavior: allow-discrete; @media (prefers-reduced-motion: reduce) { transition-property: none; @@ -18,19 +20,9 @@ @apply overflow-hidden; } - .collapse-title, - .collapse > input[type="checkbox"], - .collapse > input[type="radio"] { - @apply col-start-1 row-start-1; - } - - .collapse > input[type="checkbox"], - .collapse > input[type="radio"] { - @apply cursor-pointer appearance-none opacity-0; - } + .collapse > .collapse-content.active { + @apply visible; - .collapse > input[type="checkbox"]:checked ~ .collapse-content, - .collapse > input[type="radio"]:checked ~ .collapse-content { grid-template-rows: 1fr; } } diff --git a/src/css/vars/dark.css b/src/css/vars/dark.css index fd4d50aa..2d81d8da 100644 --- a/src/css/vars/dark.css +++ b/src/css/vars/dark.css @@ -76,7 +76,7 @@ --ds-primary-soft-color: var(--ds-primary-200); --ds-primary-soft-disabled-bg: var(--ds-primary-600); --ds-primary-soft-disabled-color: var(--ds-primary-800); - --ds-primary-soft-hover-bg: var(--ds-primary-500); + --ds-primary-soft-hover-bg: var(--ds-primary-700); --ds-primary-solid-active-bg: var(--ds-primary-600); --ds-primary-solid-bg: var(--ds-primary-600); --ds-primary-solid-color: var(--ds-common-white); diff --git a/src/css/vars/light.css b/src/css/vars/light.css index 3840271c..a1aafa90 100644 --- a/src/css/vars/light.css +++ b/src/css/vars/light.css @@ -71,12 +71,12 @@ --ds-primary-plain-color: var(--ds-primary-600); --ds-primary-plain-disabled-color: var(--ds-primary-200); --ds-primary-plain-hover-bg: var(--ds-primary-100); - --ds-primary-soft-active-bg: var(--ds-primary-300); + --ds-primary-soft-active-bg: var(--ds-primary-200); --ds-primary-soft-bg: var(--ds-primary-0); --ds-primary-soft-color: var(--ds-primary-600); --ds-primary-soft-disabled-bg: var(--ds-primary-100); --ds-primary-soft-disabled-color: var(--ds-primary-300); - --ds-primary-soft-hover-bg: var(--ds-primary-200); + --ds-primary-soft-hover-bg: var(--ds-primary-100); --ds-primary-solid-active-bg: var(--ds-primary-700); --ds-primary-solid-bg: var(--ds-primary-500); --ds-primary-solid-color: var(--ds-common-white); diff --git a/src/helpers/global-nav-active.js b/src/helpers/global-nav-active.js index ed05385b..15cf55c5 100644 --- a/src/helpers/global-nav-active.js +++ b/src/helpers/global-nav-active.js @@ -2,27 +2,45 @@ module.exports = module.exports = (navItem, { data: { - root: { page }, + root: { page, site }, }, }) => { const pageVersion = page.componentVersion?.version const pageComponent = page.component?.name + const getIgnoredActiveComponents = (items) => { + return items.reduce((acc, item) => { + if (item.ignoreActiveComponent) { + acc[item.url] = item.component + } + if (item.items) { + acc = { ...acc, ...getIgnoredActiveComponents(item.items) } + } + return acc + }, {}) + } + + const ignoredActiveComponents = getIgnoredActiveComponents(site.keys.globalNav) + const matchesComponentAndVersion = (item) => { - if (pageVersion) { - return item.component === pageComponent && item.version === pageVersion - } else { + if (ignoredActiveComponents[page.url] === pageComponent && !item.ignoreActiveComponent) { + return false + } + if (item.ignoreActiveComponent) { + return item.url === page.url + } + if (item.component) { + if (item.version && pageVersion) { + return item.component === pageComponent && item.version === pageVersion + } return item.component === pageComponent } - } - - if (navItem.component) { - return matchesComponentAndVersion(navItem) + return false } if (navItem.items) { return navItem.items.some(matchesComponentAndVersion) + } else { + return matchesComponentAndVersion(navItem) } - - return false } diff --git a/src/helpers/log-pretty.js b/src/helpers/log-pretty.js new file mode 100644 index 00000000..03d7e4a2 --- /dev/null +++ b/src/helpers/log-pretty.js @@ -0,0 +1,5 @@ +'use strict' + +module.exports = (obj) => { + return console.log(JSON.stringify(obj, null, 2)) +} diff --git a/src/helpers/nav-id.js b/src/helpers/nav-id.js new file mode 100644 index 00000000..a56a6970 --- /dev/null +++ b/src/helpers/nav-id.js @@ -0,0 +1,6 @@ +'use strict' + +module.exports = (level = 0, content) => { + if (!content) return + return `${level}-${content.replace(/\s+/g, '-').toLowerCase()}` +} diff --git a/src/js/01-nav.js b/src/js/01-nav.js index 027a3dcc..f72cfd4c 100644 --- a/src/js/01-nav.js +++ b/src/js/01-nav.js @@ -19,11 +19,11 @@ // Useful for pages with no nav links i.e. landing pages. const sideNav = document.querySelector('#side-nav') if (sideNav) { - const checkedInputs = sideNav.querySelectorAll('input[type="checkbox"]:checked, input[type="radio"]:checked') - if (!checkedInputs.length) { - const firstInput = sideNav.querySelector('input[type="checkbox"], input[type="radio"]') - if (firstInput) { - firstInput.checked = true + const activeCollapses = sideNav.querySelectorAll('.collapse > .collapse-content.active') + if (!activeCollapses.length) { + const firstCollapse = sideNav.querySelector('.collapse > .collapse-content') + if (firstCollapse) { + firstCollapse.classList.add('active') } } } diff --git a/src/js/02-on-this-page.js b/src/js/02-on-this-page.js index 725c398f..49d5bbd0 100644 --- a/src/js/02-on-this-page.js +++ b/src/js/02-on-this-page.js @@ -21,7 +21,7 @@ headingsSelector.push(headingSelector.join('>')) } var headings = find(headingsSelector.join(','), article.parentNode) - if (!headings.length) return sidebar.querySelector('.toc-menu').classList.add('hidden') + if (!headings.length) return sidebar.classList.add('!hidden') var lastActiveFragment var links = {} diff --git a/src/js/09-dropdown.js b/src/js/09-dropdown.js index a2998f62..779acced 100644 --- a/src/js/09-dropdown.js +++ b/src/js/09-dropdown.js @@ -1,3 +1,25 @@ +/** + * Dropdown Example + * + * Optional: data-trigger-type="hover" (default is "click") + * Optional: data-placement="right-start" (default is "bottom-start") + * Valid Placement Options: + * top, top-start, top-end, + * right, right-start, right-end, + * bottom, bottom-start, bottom-end, + * left, left-start, left-end + * + * + */ + ;(function () { 'use strict' @@ -11,12 +33,17 @@ }) } - const dropdownFn = (trigger, dropdown, triggerType = 'click') => { + const dropdownFn = (trigger, dropdown, triggerType = 'click', placement) => { const update = () => { computePosition(trigger, dropdown, { strategy: 'fixed', middleware: [ - autoPlacement({ alignment: 'start', allowedPlacements: ['bottom', 'bottom-start', 'bottom-end'] }), + autoPlacement( + { + alignment: 'start', + allowedPlacements: placement ? [placement] : ['bottom', 'bottom-start', 'bottom-end'], + } + ), shift(), ], }).then(({ x, y }) => { @@ -68,6 +95,8 @@ } } + trigger.ariaExpanded = false + if (triggerType === 'hover' && !isTouchDevice) { trigger.addEventListener('mouseenter', show) trigger.addEventListener('mouseenter', clearHideTimeout) @@ -84,8 +113,9 @@ // Init all dropdowns document.querySelectorAll('.dropdown').forEach((dropdown) => { const triggerType = dropdown.dataset.triggerType + const placement = dropdown.dataset.placement const trigger = dropdown.querySelector('.dropdown-trigger') const content = dropdown.querySelector('.dropdown-content') - dropdownFn(trigger, content, triggerType) + dropdownFn(trigger, content, triggerType, placement) }) })() diff --git a/src/js/10-collapse.js b/src/js/10-collapse.js new file mode 100644 index 00000000..c9006676 --- /dev/null +++ b/src/js/10-collapse.js @@ -0,0 +1,35 @@ +/** + * Collapse Example + * + *
+ * + *
+ *

Collapse Content

+ *
+ *
+ */ + +;(function () { + 'use strict' + + const collapseFn = (trigger, collapse) => { + const toggle = (e) => { + e.stopPropagation() + e.preventDefault() + collapse.classList.toggle('active') + trigger.classList.toggle('active') + trigger.ariaExpanded = trigger.ariaExpanded !== 'true' + } + trigger.ariaExpanded = false + trigger.addEventListener('click', toggle) + } + + // Init all collapses + document.querySelectorAll('.collapse').forEach((collapse) => { + const trigger = collapse.querySelector('.collapse-trigger') + const content = collapse.querySelector('.collapse-content') + collapseFn(trigger, content) + }) +})() diff --git a/src/partials/global-nav.hbs b/src/partials/global-nav.hbs index f3c41b11..a37bd01f 100644 --- a/src/partials/global-nav.hbs +++ b/src/partials/global-nav.hbs @@ -3,28 +3,30 @@ {{#each this}} {{#if ./url}} - {{#if ./home}}home{{/if}} + {{#if ./home}}home{{/if}} {{{./title}}} {{#if ./home}}
{{/if}} {{/if}} {{#if ./items}}