UNPKG

@hashicorp/design-system-components

Version:
193 lines (184 loc) 8.32 kB
import Component from '@glimmer/component'; import { deprecate } from '@ember/debug'; import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; import { registerDestructor } from '@ember/destroyable'; import { precompileTemplate } from '@ember/template-compilation'; import { g, i, n } from 'decorator-transforms/runtime'; import { setComponentTemplate } from '@ember/component'; var TEMPLATE = precompileTemplate("{{!\n Copyright (c) HashiCorp, Inc.\n SPDX-License-Identifier: MPL-2.0\n}}\n\n{{!\n THIS COMPONENT IS NOW DEPRECATED\n}}\n\n{{! IMPORTANT: we need to add \"squishies\" here (~) because otherwise the whitespace added by Ember causes the empty element to still have visible padding - See https://handlebarsjs.com/guide/expressions.html#whitespace-control }}\n\n<Hds::SideNav::Base\n class={{concat this.classNames (unless (has-block \"header\") \" hds-side-nav--is-headerless\")}}\n ...attributes\n {{on \"transitionstart\" (fn this.setTransition \"start\")}}\n {{on \"transitionend\" (fn this.setTransition \"end\")}}\n {{! @glint-expect-error - https://github.com/josemarluedke/ember-focus-trap/issues/86 }}\n {{focus-trap isActive=this.shouldTrapFocus}}\n {{did-insert this.didInsert}}\n>\n <:root>\n {{#if this.hasA11yRefocus}}\n <NavigationNarrator\n @routeChangeValidator={{@a11yRefocusRouteChangeValidator}}\n @skipTo={{this.a11yRefocusSkipTo}}\n @skipText={{@a11yRefocusSkipText}}\n @navigationText={{@a11yRefocusNavigationText}}\n @excludeAllQueryParams={{@a11yRefocusExcludeAllQueryParams}}\n />\n {{/if}}\n {{#if this.showToggleButton}}\n {{! template-lint-disable no-invalid-interactive}}\n <div class=\"hds-side-nav__overlay\" {{on \"click\" this.toggleMinimizedStatus}} />\n {{! template-lint-enable no-invalid-interactive}}\n <Hds::SideNav::ToggleButton\n aria-labelledby=\"hds-side-nav-header\"\n aria-expanded={{if this.isMinimized \"false\" \"true\"}}\n @icon={{if this.isMinimized \"chevrons-right\" \"chevrons-left\"}}\n {{on \"click\" this.toggleMinimizedStatus}}\n />\n {{/if}}\n </:root>\n <:header as |Header|>\n {{~yield (hash Header=Header isMinimized=this.isMinimized) to=\"header\"~}}\n </:header>\n <:body as |Body|>\n {{~yield (hash Body=Body isMinimized=this.isMinimized) to=\"body\"~}}\n </:body>\n <:footer as |Footer|>\n {{~yield (hash Footer=Footer isMinimized=this.isMinimized) to=\"footer\"~}}\n </:footer>\n</Hds::SideNav::Base>"); /** * Copyright (c) HashiCorp, Inc. * SPDX-License-Identifier: MPL-2.0 */ class HdsSideNav extends Component { static { g(this.prototype, "isAnimating", [tracked], function () { return false; }); } #isAnimating = (i(this, "isAnimating"), void 0); static { g(this.prototype, "isDesktop", [tracked], function () { return true; }); } #isDesktop = (i(this, "isDesktop"), void 0); static { g(this.prototype, "isMinimized", [tracked], function () { return false; }); } #isMinimized = (i(this, "isMinimized"), void 0); desktopMQ; containersToHide; hasA11yRefocus = this.args.hasA11yRefocus ?? true; a11yRefocusSkipTo = '#' + (this.args.a11yRefocusSkipTo ?? 'hds-main'); desktopMQVal = getComputedStyle(document.documentElement).getPropertyValue('--hds-app-desktop-breakpoint'); constructor(owner, args) { super(owner, args); // sets the default minimized state on 'desktop' viewports this.isMinimized = this.args.isMinimized ?? false; this.desktopMQ = window.matchMedia(`(min-width:${this.desktopMQVal})`); this.addEventListeners(); registerDestructor(this, () => { this.removeEventListeners(); }); deprecate('The `Hds::SideNav` component is now deprecated and will be removed in the next major version of `@hashicorp/design-system-components`. Use `Hds::AppSideNav` instead.', false, { id: 'hds.components.sidenav', until: '6.0.0', url: 'https://helios.hashicorp.design/components/side-nav?tab=version%20history#4140', for: '@hashicorp/design-system-components', since: { available: '4.19.0', enabled: '5.0.0' } }); } addEventListeners() { // eslint-disable-next-line @typescript-eslint/unbound-method document.addEventListener('keydown', this.escapePress, true); // eslint-disable-next-line @typescript-eslint/unbound-method this.desktopMQ.addEventListener('change', this.updateDesktopVariable, true); // if not instantiated as minimized via arguments if (!this.args.isMinimized) { // set initial state based on viewport using a "synthetic" event const syntheticEvent = new MediaQueryListEvent('change', { matches: this.desktopMQ.matches, media: this.desktopMQ.media }); this.updateDesktopVariable(syntheticEvent); } } removeEventListeners() { // eslint-disable-next-line @typescript-eslint/unbound-method document.removeEventListener('keydown', this.escapePress, true); this.desktopMQ.removeEventListener('change', // eslint-disable-next-line @typescript-eslint/unbound-method this.updateDesktopVariable, true); } // controls if the component reacts to viewport changes get isResponsive() { return this.args.isResponsive ?? true; } // controls if users can collapse the appsidenav on 'desktop' viewports get isCollapsible() { return this.args.isCollapsible ?? false; } get shouldTrapFocus() { return this.isResponsive && !this.isDesktop && !this.isMinimized; } get showToggleButton() { return this.isResponsive && !this.isDesktop || this.isCollapsible; } get classNames() { const classes = []; // `hds-side-nav` is already set by the "Hds::SideNav::Base" component // add specific class names for the different possible states if (this.isResponsive) { classes.push('hds-side-nav--is-responsive'); } if (!this.isDesktop && this.isResponsive) { classes.push('hds-side-nav--is-mobile'); } else { classes.push('hds-side-nav--is-desktop'); } if (this.isMinimized && this.isResponsive) { classes.push('hds-side-nav--is-minimized'); } else { classes.push('hds-side-nav--is-not-minimized'); } if (this.isAnimating) { classes.push('hds-side-nav--is-animating'); } return classes.join(' '); } synchronizeInert() { this.containersToHide?.forEach(element => { if (this.isMinimized) { element.setAttribute('inert', ''); } else { element.removeAttribute('inert'); } }); } escapePress(event) { if (event.key === 'Escape' && !this.isMinimized && !this.isDesktop) { this.isMinimized = true; this.synchronizeInert(); } } static { n(this.prototype, "escapePress", [action]); } toggleMinimizedStatus() { this.isMinimized = !this.isMinimized; this.synchronizeInert(); const { onToggleMinimizedStatus } = this.args; if (typeof onToggleMinimizedStatus === 'function') { onToggleMinimizedStatus(this.isMinimized); } } static { n(this.prototype, "toggleMinimizedStatus", [action]); } didInsert(element) { this.containersToHide = element.querySelectorAll('.hds-side-nav-hide-when-minimized'); } static { n(this.prototype, "didInsert", [action]); } setTransition(phase, event) { // we only want to respond to `width` animation/transitions if (event.propertyName !== 'width') { return; } if (phase === 'start') { this.isAnimating = true; } else { this.isAnimating = false; } } static { n(this.prototype, "setTransition", [action]); } updateDesktopVariable(event) { this.isDesktop = event.matches; // automatically minimize on narrow viewports (when not in desktop mode) this.isMinimized = !this.isDesktop; this.synchronizeInert(); const { onDesktopViewportChange } = this.args; if (typeof onDesktopViewportChange === 'function') { onDesktopViewportChange(this.isDesktop); } } static { n(this.prototype, "updateDesktopVariable", [action]); } } setComponentTemplate(TEMPLATE, HdsSideNav); export { HdsSideNav as default }; //# sourceMappingURL=index.js.map