diff --git a/elements/rh-navigation-secondary-dsd/README.md b/elements/rh-navigation-secondary-dsd/README.md new file mode 100644 index 0000000000..d95308e5b6 --- /dev/null +++ b/elements/rh-navigation-secondary-dsd/README.md @@ -0,0 +1,11 @@ +# Navigation Secondary Dsd +Add a description of the component here. + +## Usage +Describe how best to use this web component along with best practices. + +```html + + + +``` diff --git a/elements/rh-navigation-secondary-dsd/demo/rh-navigation-secondary-dsd.html b/elements/rh-navigation-secondary-dsd/demo/rh-navigation-secondary-dsd.html new file mode 100644 index 0000000000..2f9e182cc1 --- /dev/null +++ b/elements/rh-navigation-secondary-dsd/demo/rh-navigation-secondary-dsd.html @@ -0,0 +1,93 @@ + + + Red Hat Ansible Automation Platform + + + Call to Action + + +
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sagittis, ex eget congue consectetur, odio lorem tincidunt risus, eget viverra mauris nunc id quam. In eu risus et tortor luctus vehicula. Suspendisse scelerisque posuere est at imperdiet. Aliquam ut tempor ante. Sed ac egestas mauris, in pretium diam. Nam et faucibus felis. Fusce in porttitor sem. Proin commodo mi enim, sed molestie nunc dictum accumsan. Integer a suscipit lorem, a ornare turpis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam non ornare arcu. Donec vitae rhoncus metus, eget bibendum diam. Ut tincidunt arcu non risus maximus accumsan. Praesent vel purus purus. +

+

+ Vestibulum fringilla augue a lorem maximus imperdiet. Interdum et malesuada fames ac ante ipsum primis in faucibus. Suspendisse et augue sit amet arcu aliquam fringilla. Mauris vehicula, lacus non ultricies laoreet, purus mauris hendrerit quam, nec tincidunt velit leo id neque. Nam consectetur mauris pulvinar mattis posuere. Proin in nisl sed mauris dignissim vehicula. Nulla ut elit sodales, tempor ante ut, rutrum ipsum. Pellentesque tempus in nisl a egestas. Fusce ornare urna et orci vehicula, in euismod libero cursus. Cras non interdum sem, ut condimentum quam. Nam vestibulum quam massa, cursus interdum diam facilisis quis. Praesent ut quam ut augue varius tempor. +

+

+ Nunc ac hendrerit justo, a placerat urna. Nam finibus posuere leo eget vulputate. In lectus nisi, porta vitae orci in, pharetra consectetur leo. Cras ultricies orci et dolor hendrerit tincidunt. Etiam eget mauris neque. Ut a sollicitudin enim. Curabitur at risus ultrices, faucibus elit sit amet, dictum odio. Mauris tristique viverra massa, at bibendum eros vulputate nec. +

+

+ Nam risus sapien, lacinia id massa sit amet, faucibus finibus nisi. Mauris interdum scelerisque sapien. Vestibulum tincidunt ac turpis sed tristique. Integer ac magna quis neque venenatis tristique. Vivamus elementum dolor quis massa sollicitudin tincidunt. Nulla accumsan, nibh eu rutrum porta, libero leo vehicula odio, ut luctus enim nibh tempor mauris. Suspendisse pellentesque erat varius erat efficitur, id condimentum sapien congue. Quisque sit amet magna rutrum, posuere lorem vel, auctor dolor. Donec et magna libero. Mauris ut lacinia magna. Donec dignissim sapien id sem eleifend fermentum. Nullam semper eros ac mattis lobortis. Nulla facilisi. +

+

+ In hac habitasse platea dictumst. Fusce sed tempor metus. Proin condimentum turpis at eros posuere, sed vestibulum turpis faucibus. Sed ornare urna odio, vitae suscipit enim tempor eu. Fusce vitae magna ac augue accumsan facilisis. In hac habitasse platea dictumst. Proin vehicula risus sed odio finibus, at semper lectus consequat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Integer neque tortor, lacinia sit amet sagittis eget, scelerisque et nunc. Cras congue luctus cursus. Sed vitae ipsum dui. In non risus porttitor libero dapibus interdum at ut lacus. Sed finibus suscipit rhoncus. Aliquam erat volutpat. Sed nec accumsan dolor. +

+
+ + + + + + + + + diff --git a/elements/rh-navigation-secondary-dsd/docs/00-overview.md b/elements/rh-navigation-secondary-dsd/docs/00-overview.md new file mode 100644 index 0000000000..8a507f46a0 --- /dev/null +++ b/elements/rh-navigation-secondary-dsd/docs/00-overview.md @@ -0,0 +1,2 @@ +## When to use + diff --git a/elements/rh-navigation-secondary-dsd/docs/30-code.md b/elements/rh-navigation-secondary-dsd/docs/30-code.md new file mode 100644 index 0000000000..7d8cdf686d --- /dev/null +++ b/elements/rh-navigation-secondary-dsd/docs/30-code.md @@ -0,0 +1 @@ +### System Integration \ No newline at end of file diff --git a/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-dropdown.css b/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-dropdown.css new file mode 100644 index 0000000000..d8f7b336b9 --- /dev/null +++ b/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-dropdown.css @@ -0,0 +1,94 @@ +:host { + display: flex; + height: 100%; + align-items: center; +} + +details { + border-inline-start: var(--rh-border-width-lg) solid transparent; + border-inline-end: var(--rh-border-width-sm) solid transparent; + width: 100%; + + & > summary { + --rh-icon-size: 12px; + + cursor: pointer; + list-style: none; + display: flex; + align-items: center; + height: max-content; + color: var(--_nav-link-color) !important; + font-size: var(--rh-font-size-body-text-md, 1rem); + font-weight: 400; + padding: var(--rh-space-lg, 16px) var(--rh-space-xl, 24px); + text-decoration: none !important; + text-align: center; + justify-content: space-between; + + &::marker, + &::-webkit-details-marker { + display: none; + } + } + + #details-content { + background-color: var(--rh-color-surface-lightest); + } + + &[open] { + border-inline-start-color: var(--rh-color-text-brand-on-light); + border-inline-end-color: var(--rh-color-border-subtle-on-light); + box-shadow: var(--rh-box-shadow-sm); + + & summary { + rh-icon { + rotate: 180deg; + } + } + } +} + +:host(:defined) { + & details { + @container (min-width: 992px) { + height: 100%; + } + + & > summary { + @container (min-width: 992px) { + display: flex; + height: 100%; + align-items: center; + padding-block: 0; + padding-inline: var(--rh-space-md); + gap: var(--rh-space-sm); + } + } + + & > #details-content { + @container (min-width: 992px) { + position: absolute; + inset-inline: 0; + padding: 0; + box-shadow: var(--rh-box-shadow-sm); + max-height: calc(100vh - var(--rh-space-4xl) - var(--_nav-min-height)); + /* stylelint-disable-next-line rhds/no-unknown-token-name */ + z-index: var(--rh-navigation-secondary-z-index, 103); + } + } + + &[open] { + @container (min-width: 992px) { + border-inline-start-color: transparent; + border-inline-end-color: transparent; + box-shadow: unset; + } + + & summary { + @container (min-width: 992px) { + background-color: var(--rh-color-surface-lightest); + } + } + } + } +} diff --git a/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-dropdown.ts b/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-dropdown.ts new file mode 100644 index 0000000000..ee1e5a6e9a --- /dev/null +++ b/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-dropdown.ts @@ -0,0 +1,94 @@ +import { LitElement, html, isServer } from 'lit'; +import { customElement } from 'lit/decorators/custom-element.js'; +import { state } from 'lit/decorators/state.js'; +import { query } from 'lit/decorators/query.js'; +import { classMap } from 'lit/directives/class-map.js'; + +import { observes } from '@patternfly/pfe-core/decorators.js'; +import { SlotController } from '@patternfly/pfe-core/controllers/slot-controller.js'; +import { ComposedEvent } from '@patternfly/pfe-core/core.js'; + +import '@rhds/elements/rh-surface/rh-surface.js'; + +import styles from './rh-navigation-secondary-dsd-dropdown.css'; + + +export class NavigationSecondaryDsdDropdownEvent extends ComposedEvent { + constructor( + public open: boolean, + public toggle: RhNavigationSecondaryDsdDropdown, + ) { + super('expand-request'); + } +} + +/* Note breaking changes + - Removal of part[container] as the element has switched to a details > summary + - Changing the slot names to reflect this change to details > summary (removal of menu opting for default slot) + - Changing API of expanded to reflect the details summary open attribute + - Changing the exported Event property to reflect the open attribute instead of reflected + - Addition of a public close method + - Addition of a public open method +*/ + +@customElement('rh-navigation-secondary-dsd-dropdown') +export class RhNavigationSecondaryDsdDropdown extends LitElement { + static readonly styles = [styles]; + + private _slots = new SlotController(this, { slots: ['link', 'menu'] }); + + private _highlight = false; + + private _mo = new MutationObserver(this._mutationsCallback.bind(this)); + + @query('details') _details!: HTMLDetailsElement; + + @state() _open = false; + + connectedCallback(): void { + super.connectedCallback(); + if (!isServer) { + this._mo.observe(this, { attributeFilter: ['aria-current'], childList: true, subtree: true }); + } + } + + render() { + const classes = { 'highlight': this._highlight }; + return html` +
+ + + + +
+
+ `; + } + + + private _detailsToggle() { + this._open = this._details.open; + this.dispatchEvent(new NavigationSecondaryDsdDropdownEvent(this._open, this)); + } + + private _mutationsCallback() { + // if the [aria-current-page] link is a child of the default slot ensure the state of the highlight + const [dropdownMenu] = this._slots.getSlotted(''); + this._highlight = dropdownMenu.querySelector('[aria-current="page"]') ? true : false; + this.requestUpdate(); + } + + public close() { + this._details.open = false; + } + + public open() { + this._details.open = true; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'rh-navigation-secondary-dsd-dropdown': RhNavigationSecondaryDsdDropdown; + } +} diff --git a/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-lightdom.css b/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-lightdom.css new file mode 100644 index 0000000000..12bdec824b --- /dev/null +++ b/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-lightdom.css @@ -0,0 +1,72 @@ +rh-navigation-secondary-dsd { + & > [slot='nav'] { + & > li { + max-width: 100%; + border-block-start: var(--rh-border-width-sm) solid var(--rh-color-border-subtle-on-light); + + &:last-of-type { + border-block-end: var(--rh-border-width-sm) solid var(--rh-color-border-subtle-on-light); + } + + & > a { + list-style: none; + display: flex; + align-items: center; + height: 100%; + color: var(--_nav-link-color) !important; + font-size: var(--rh-font-size-body-text-md); + font-weight: 400; + padding: var(--rh-space-lg) var(--rh-space-xl); + text-decoration: none !important; + text-align: center; + border-inline-start: var(--rh-border-width-lg) solid transparent; + border-inline-end: var(--rh-border-width-sm) solid transparent; + border-block-start: var(--rh-border-width-lg) solid transparent; + + &[aria-current='page'] { + border-block-start-color: var(--rh-color-brand-red); + } + } + + & rh-navigation-secondary-dsd-dropdown { + border-block-start: var(--rh-border-width-lg) solid transparent; + + &[aria-current='page'] { + border-block-start-color: var(--rh-color-brand-red); + } + } + } + } + + & > [slot='logo'] { + border-block-start: var(--rh-border-width-lg) solid transparent; + + &[aria-current='page'] { + border-block-start-color: var(--rh-color-brand-red); + } + } + + /* explict if defined only if js loaded */ + &:defined { + & > [slot='nav'] { + & > li { + @container (min-width: 992px) { + border-block-start: none; + height: 100%; + align-items: center; + display: flex; + + &:last-of-type { + border-block-end: none; + } + } + } + + & > a { + @container (min-width: 992px) { + padding: 0; + } + } + } + } +} diff --git a/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-menu-section.css b/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-menu-section.css new file mode 100644 index 0000000000..b4a94621ec --- /dev/null +++ b/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-menu-section.css @@ -0,0 +1,39 @@ +:host { + display: block; +} + +section { + & slot[name='header']::slotted(:is(h1,h2,h3,h4,h5,h6)) { + font-family: var(--rh-font-family-heading, RedHatDisplay, 'Red Hat Display', 'Noto Sans Arabic', 'Noto Sans Hebrew', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans Malayalam', 'Noto Sans SC', 'Noto Sans TC', 'Noto Sans Thai', Helvetica, Arial, sans-serif) !important; + padding: 0 !important; + font-size: var(--rh-font-size-body-text-md, 1rem) !important; + font-weight: 500 !important; + margin: 0 0 var(--rh-space-lg, 16px) !important; + + @container (min-width: 992px) { + padding: 0 !important; + } + } + + & slot[name='links']::slotted(:is(ul, ol)) { + list-style: none !important; + margin: 0 !important; + padding: 0 !important; + display: flex !important; + flex-direction: column !important; + gap: var(--rh-font-size-body-text-md, 1rem); + + @container (min-width: 992px) { + padding: 0 !important; + margin: 0 !important; + } + } + + & slot[name='cta']::slotted(*) { + padding: var(--rh-space-xl, 24px) 0 0; + + &:last-of-type { + padding: var(--rh-space-xl, 24px) 0; + } + } +} diff --git a/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-menu-section.ts b/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-menu-section.ts new file mode 100644 index 0000000000..b09fb12fc7 --- /dev/null +++ b/elements/rh-navigation-secondary-dsd/rh-navigation-secondary-dsd-menu-section.ts @@ -0,0 +1,74 @@ +import { html, LitElement } from 'lit'; +import { customElement } from 'lit/decorators/custom-element.js'; + +import { getRandomId } from '@patternfly/pfe-core/functions/random.js'; +import { Logger } from '@patternfly/pfe-core/controllers/logger.js'; + +import { isHeadingElement } from '../../lib/functions.js'; + +import styles from './rh-navigation-secondary-dsd-menu-section.css'; + +/** + * A menu section which auto upgrades accessibility for headers and sibling list + * @summary 'A menu section which auto upgrades accessibility for headers and sibling list' + * @slot header - Adds a header tag to section, expects `

|

|

|

|

|
` element + * @slot links - Adds a ul tag to section, expects `