@vaadin/vaadin-app-layout
Advanced tools
Comparing version 2.0.0-alpha1 to 2.0.0-alpha2
@@ -13,3 +13,3 @@ { | ||
"name": "@vaadin/vaadin-app-layout", | ||
"version": "2.0.0-alpha1", | ||
"version": "2.0.0-alpha2", | ||
"main": "vaadin-app-layout.js", | ||
@@ -16,0 +16,0 @@ "author": "Vaadin Ltd", |
@@ -118,3 +118,3 @@ [![npm version](https://badgen.net/npm/v/@vaadin/vaadin-app-layout)](https://www.npmjs.com/package/@vaadin/vaadin-app-layout) | ||
We are using [ESLint](http://eslint.org/) for linting JavaScript code. You can check if your code is following our standards by running `gulp lint`, which will automatically lint all `.js` files as well as JavaScript snippets inside `.html` files. | ||
We are using [ESLint](http://eslint.org/) for linting JavaScript code. You can check if your code is following our standards by running `npm run lint`, which will automatically lint all `.js` files as well as JavaScript snippets inside `.html` files. | ||
@@ -124,3 +124,3 @@ | ||
- Make sure your code is compliant with our code linters: `gulp lint` | ||
- Make sure your code is compliant with our code linters: `npm run lint` | ||
- Check that tests are passing: `polymer test` | ||
@@ -127,0 +127,0 @@ - [Submit a pull request](https://www.digitalocean.com/community/tutorials/how-to-create-a-pull-request-on-github) with detailed title and description |
/** | ||
@license | ||
Vaadin Navbar Layout | ||
Vaadin App Layout | ||
Copyright (C) 2019 Vaadin Ltd | ||
@@ -11,3 +11,5 @@ This program is available under Apache License Version 2.0, available at https://vaadin.com/license/ | ||
import { PolymerElement } from '@polymer/polymer/polymer-element.js'; | ||
import { AppLayoutMixin } from './vaadin-app-layout-mixin.js'; | ||
import { beforeNextRender, afterNextRender } from '@polymer/polymer/lib/utils/render-status.js'; | ||
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js'; | ||
import { ElementMixin } from '@vaadin/vaadin-element-mixin/vaadin-element-mixin.js'; | ||
import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js'; | ||
@@ -17,12 +19,62 @@ import { html } from '@polymer/polymer/lib/utils/html-tag.js'; | ||
/** | ||
* `<vaadin-app-layout>` is a Web Component providing a quick and easy way to get a common application layout structure done. | ||
* | ||
* ``` | ||
* <vaadin-app-layout [drawer-first]> | ||
* <vaadin-drawer-toggle slot="navbar [touch-optimized]"></vaadin-drawer-toggle> | ||
* <h3 slot="navbar [touch-optimized]">Company Name</h3> | ||
* <vaadin-tabs orientation="vertical" slot="drawer"> | ||
* <vaadin-tab>Menu item 1</vaadin-tab> | ||
* </vaadin-tabs> | ||
* <!-- Everything else will be the page content --> | ||
* <div> | ||
* <h3>Page title</h3> | ||
* <p>Page content</p> | ||
* </div> | ||
* </vaadin-app-layout> | ||
* ``` | ||
* | ||
* For best results, the component should be added to the root level of your application (i.e., as a direct child of `<body>`) | ||
* | ||
* ### Styling | ||
* | ||
* The following Shadow DOM parts of the `<vaadin-app-layout>` are available for styling: | ||
* | ||
* Part name | Description | ||
* --------------|---------------------------------------------------------| | ||
* `navbar` | Container for the navigation bar | ||
* `drawer` | Container for the drawer area | ||
* `content` | Container for page content. | ||
* | ||
* See [ThemableMixin – how to apply styles for shadow parts](https://github.com/vaadin/vaadin-themable-mixin/wiki) | ||
* | ||
* ### Component's slots | ||
* | ||
* The following slots are available to be set | ||
* | ||
* Slot name | Description | ||
* -------------------|---------------------------------------------------| | ||
* no name | Default container for the page content | ||
* `navbar ` | Container for the top navbar area | ||
* `drawer` | Container for an application menu | ||
* `touch-optimized` | Container for the bottom navbar area (only visible for mobile devices) | ||
* | ||
* | ||
* See examples of setting the content into slots in the live demos. | ||
* | ||
* @memberof Vaadin | ||
* @mixes Vaadin.AppLayoutMixin | ||
* @extends Polymer.Element | ||
* @mixes Vaadin.ElementMixin | ||
* @mixes Vaadin.ThemableMixin | ||
* @demo demo/index.html | ||
*/ | ||
class AppLayoutElement extends AppLayoutMixin(PolymerElement) { | ||
class AppLayoutElement extends ElementMixin(ThemableMixin(PolymerElement)) { | ||
static get template() { | ||
return html` | ||
<style include="vaadin-app-layout-mixin"> | ||
<style> | ||
:host { | ||
display: block; | ||
box-sizing: border-box; | ||
height: 100%; | ||
--vaadin-app-layout-transition: 200ms; | ||
transition: padding var(--vaadin-app-layout-transition); | ||
--vaadin-app-layout-touch-optimized: false; | ||
@@ -36,2 +88,10 @@ --vaadin-app-layout-navbar-offset-top: var(--_vaadin-app-layout-navbar-offset-size); | ||
:host([hidden]) { | ||
display: none !important; | ||
} | ||
:host([no-anim]) { | ||
--vaadin-app-layout-transition: none !important; | ||
} | ||
:host([drawer-opened]) { | ||
@@ -43,7 +103,14 @@ --vaadin-app-layout-drawer-offset-left: var(--_vaadin-app-layout-drawer-offset-size); | ||
--vaadin-app-layout-drawer-offset-left: 0; | ||
--vaadin-app-layout-navbar-offset-top: 0; | ||
--vaadin-app-layout-navbar-offset-bottom: 0; | ||
--vaadin-app-layout-navbar-offset-left: 0; | ||
} | ||
:host(:not([no-scroll])) [content] { | ||
overflow: auto; | ||
-webkit-overflow-scrolling: touch; | ||
} | ||
[content] { | ||
height: 100%; | ||
} | ||
@media (pointer: coarse) and (max-width: 800px) and (min-height: 500px) { | ||
@@ -75,3 +142,3 @@ :host { | ||
:host([orientation="vertical"]) [part="navbar"][bottom] { | ||
[part="navbar"][bottom] { | ||
top: auto; | ||
@@ -94,2 +161,3 @@ bottom: 0; | ||
padding: var(--safe-area-inset-top) 0 var(--safe-area-inset-bottom) var(--safe-area-inset-left); | ||
outline: none; | ||
} | ||
@@ -122,2 +190,7 @@ | ||
:host([overlay]) [part="drawer"] { | ||
top: 0; | ||
bottom: 0; | ||
} | ||
:host([overlay]) [part="drawer"], | ||
@@ -147,16 +220,9 @@ :host([overlay]) [part="backdrop"] { | ||
} | ||
:host([orientation="horizontal"]) { | ||
--vaadin-app-layout-navbar-offset-top: 0; | ||
--vaadin-app-layout-navbar-offset-left: var(--_vaadin-app-layout-navbar-offset-size); | ||
} | ||
:host([orientation="horizontal"]) [part="navbar"] { | ||
right: auto; | ||
bottom: var(--vaadin-viewport-offset-bottom, 0); | ||
} | ||
</style> | ||
<div part="navbar"> | ||
<slot name="navbar"></slot> | ||
</div> | ||
<div part="backdrop" on-click="_close" on-touchstart="_close"></div> | ||
<div part="drawer"> | ||
<slot name="drawer" id="drawer"></slot> | ||
<div part="drawer" id="drawer"> | ||
<slot name="drawer" id="drawerSlot"></slot> | ||
</div> | ||
@@ -166,5 +232,2 @@ <div content=""> | ||
</div> | ||
<div part="navbar"> | ||
<slot name="navbar"></slot> | ||
</div> | ||
<div part="navbar" bottom="" hidden=""> | ||
@@ -181,3 +244,3 @@ <slot name="navbar-bottom"></slot> | ||
static get version() { | ||
return '2.0.0-alpha1'; | ||
return '2.0.0-alpha2'; | ||
} | ||
@@ -187,24 +250,35 @@ | ||
return { | ||
// vertical (default) or horizontal | ||
orientation: { | ||
type: String, | ||
value: 'vertical', | ||
reflectToAttribute: true | ||
}, | ||
/** | ||
* Defines how the navbar and the drawer will interact with each other on desktop view when the drawer is opened. | ||
* - By default, the navbar takes the full available width and moves the drawer down. | ||
* - If `drawer-first` is set, then the drawer will move the navbar, taking the full available height. | ||
*/ | ||
drawerFirst: { | ||
type: Boolean, | ||
notify: true, | ||
reflectToAttribute: true | ||
}, | ||
/** | ||
* Controls whether the drawer is opened (visible) or not. | ||
* Its default value depends on the viewport: | ||
* - `true`, for desktop size views | ||
* - `false`, for mobile size views | ||
*/ | ||
drawerOpened: { | ||
type: Boolean, | ||
notify: true, | ||
value: true, | ||
reflectToAttribute: true | ||
reflectToAttribute: true, | ||
observer: '_drawerOpenedObserver' | ||
}, | ||
// Drawer is an overlay on top of the content | ||
// Controlled via CSS using --vaadin-app-layout-drawer-overlay: true|false; | ||
/** | ||
* Drawer is an overlay on top of the content | ||
* Controlled via CSS using `--vaadin-app-layout-drawer-overlay: true|false`; | ||
*/ | ||
overlay: { | ||
type: Boolean, | ||
notify: true, | ||
readOnly: true, | ||
value: false, | ||
@@ -216,19 +290,64 @@ reflectToAttribute: true | ||
constructor() { | ||
super(); | ||
// TODO(jouni): might want to debounce | ||
this.__boundResizeListener = this._resize.bind(this); | ||
this.__drawerToggleClickListener = this._drawerToggleClick.bind(this); | ||
} | ||
/** | ||
* @private | ||
*/ | ||
connectedCallback() { | ||
super.connectedCallback(); | ||
this._blockAnimationUntilAfterNextRender(); | ||
window.addEventListener('resize', this.__boundResizeListener); | ||
this.addEventListener('drawer-toggle-click', this.__drawerToggleClickListener); | ||
// Wait for all children to upgrade before trying to measure sizes | ||
if (window.HTMLImports && !window.HTMLImports.useNative) { | ||
Array.from(this.querySelectorAll('*')).forEach(child => { | ||
if (child.localName.indexOf('-') > -1) { | ||
window.customElements.whenDefined(child.localName).then(() => { | ||
// TODO(jouni): might want to debounce | ||
beforeNextRender(this, this._afterFirstRender); | ||
}); | ||
} | ||
}); | ||
} else { | ||
beforeNextRender(this, this._afterFirstRender); | ||
} | ||
this._updateTouchOptimizedMode(); | ||
this._setupDrawerToggleClickListener(); | ||
this._navbarChildObserver = new FlattenedNodesObserver(this.$.drawer, (info) => { | ||
this._navbarChildObserver = new FlattenedNodesObserver(this.$.drawerSlot, (info) => { | ||
this._updateDrawerSize(); | ||
}); | ||
this._updateDrawerSize(); | ||
this._updateOverlayMode(); | ||
} | ||
_setupDrawerToggleClickListener() { | ||
this.toggleClickListener = this.addEventListener('drawer-toggle-click', this._drawerToggleClickListener); | ||
/** | ||
* @private | ||
*/ | ||
disconnectedCallback() { | ||
super.disconnectedCallback(); | ||
this._navbarChildObserver && this._navbarChildObserver.disconnect(); | ||
window.removeEventListener('resize', this.__boundResizeListener); | ||
this.removeEventListener('drawer-toggle-click', this.__drawerToggleClickListener); | ||
} | ||
_drawerToggleClickListener(e) { | ||
_isShadyCSS() { | ||
return window.ShadyCSS && !window.ShadyCSS.nativeCss; | ||
} | ||
_afterFirstRender() { | ||
this._blockAnimationUntilAfterNextRender(); | ||
this._updateOffsetSize(); | ||
} | ||
_drawerToggleClick(e) { | ||
e.stopPropagation(); | ||
@@ -250,11 +369,4 @@ this.drawerOpened = !this.drawerOpened; | ||
disconnectedCallback() { | ||
super.disconnectedCallback(); | ||
this._navbarChildObserver && this._navbarChildObserver.disconnect(); | ||
this.removeEventListener('drawer-toggle-click', this._drawerToggleClickListener); | ||
} | ||
_resize() { | ||
super._resize(); | ||
this._blockAnimationUntilAfterNextRender(); | ||
this._updateTouchOptimizedMode(); | ||
@@ -265,34 +377,62 @@ this._updateOverlayMode(); | ||
_updateOffsetSize() { | ||
super._updateOffsetSize(); | ||
const navbar = this.shadowRoot.querySelector('[part="navbar"]'); | ||
const navbarRect = navbar.getBoundingClientRect(); | ||
// TODO(jouni): use shady css if we want to support IE11 | ||
if (this.orientation == 'vertical') { | ||
const navbarBottom = this.shadowRoot.querySelector('[part="navbar"][bottom]'); | ||
const navbarBottomRect = navbarBottom.getBoundingClientRect(); | ||
if (this._isShadyCSS()) { | ||
window.ShadyCSS.styleSubtree(this, { | ||
'--_vaadin-app-layout-navbar-offset-size': navbarRect.height + 'px', | ||
'--_vaadin-app-layout-navbar-offset-size-bottom': navbarBottomRect.height + 'px' | ||
}); | ||
} else { | ||
this.style.setProperty('--_vaadin-app-layout-navbar-offset-size', navbarRect.height + 'px'); | ||
const navbarBottom = this.shadowRoot.querySelector('[part="navbar"][bottom]'); | ||
const navbarBottomRect = navbarBottom.getBoundingClientRect(); | ||
this.style.setProperty('--_vaadin-app-layout-navbar-offset-size-bottom', navbarBottomRect.height + 'px'); | ||
} else { | ||
this.style.setProperty('--_vaadin-app-layout-navbar-offset-size', navbarRect.width + 'px'); | ||
} | ||
const drawer = this.shadowRoot.querySelector('[part="drawer"]'); | ||
const drawer = this.$.drawer; | ||
const drawerRect = drawer.getBoundingClientRect(); | ||
// TODO(jouni): use shady css if we want to support IE11 | ||
this.style.setProperty('--_vaadin-app-layout-drawer-offset-size', drawerRect.width + 'px'); | ||
if (this._isShadyCSS()) { | ||
window.ShadyCSS.styleSubtree(this, { | ||
'--_vaadin-app-layout-drawer-offset-size': drawerRect.width + 'px', | ||
// Have to update both because ShadyCSS may not apply the one below if not in use | ||
'--vaadin-app-layout-drawer-offset-left': 'var(--_vaadin-app-layout-drawer-offset-size)' | ||
}); | ||
} else { | ||
this.style.setProperty('--_vaadin-app-layout-drawer-offset-size', drawerRect.width + 'px'); | ||
} | ||
} | ||
_drawerOpenedObserver() { | ||
const drawer = this.$.drawer; | ||
drawer.removeAttribute('tabindex'); | ||
if (this.overlay) { | ||
if (this.drawerOpened) { | ||
drawer.setAttribute('tabindex', 0); | ||
drawer.focus(); | ||
} | ||
} | ||
} | ||
_updateOverlayMode() { | ||
// TODO(jouni): use shady css if we want to support IE11 | ||
let overlay = getComputedStyle(this).getPropertyValue('--vaadin-app-layout-drawer-overlay'); | ||
overlay = overlay.trim().toLowerCase() == 'true'; | ||
const overlay = this._getCustomPropertyValue('--vaadin-app-layout-drawer-overlay') == 'true'; | ||
const drawer = this.$.drawer; | ||
this.overlay = overlay; | ||
this._setOverlay(overlay); | ||
if (this.overlay) { | ||
this.drawerOpened = false; | ||
drawer.setAttribute('role', 'dialog'); | ||
drawer.setAttribute('aria-modal', 'true'); | ||
drawer.setAttribute('aria-label', 'drawer'); | ||
} else { | ||
drawer.removeAttribute('role'); | ||
drawer.removeAttribute('aria-modal'); | ||
drawer.removeAttribute('aria-label'); | ||
} | ||
@@ -308,6 +448,17 @@ | ||
_getCustomPropertyValue(customProperty) { | ||
let customPropertyValue; | ||
if (this._isShadyCSS()) { | ||
window.ShadyCSS.styleSubtree(this); | ||
customPropertyValue = window.ShadyCSS.getComputedStyleValue(this, customProperty); | ||
} else { | ||
customPropertyValue = getComputedStyle(this).getPropertyValue(customProperty); | ||
} | ||
return (customPropertyValue || '').trim().toLowerCase(); | ||
} | ||
_updateTouchOptimizedMode() { | ||
// TODO(jouni): use shady css if we want to support IE11 | ||
let touchOptimized = getComputedStyle(this).getPropertyValue('--vaadin-app-layout-touch-optimized'); | ||
touchOptimized = touchOptimized.trim().toLowerCase() == 'true'; | ||
const touchOptimized = this._getCustomPropertyValue('--vaadin-app-layout-touch-optimized') == 'true'; | ||
@@ -323,3 +474,3 @@ const navbarBottom = this.shadowRoot.querySelector('[part="navbar"][bottom]'); | ||
if (this.orientation == 'vertical' && touchOptimized && navbar.__touchOptimized) { | ||
if (touchOptimized && navbar.__touchOptimized) { | ||
navbar.setAttribute('slot', 'navbar-bottom'); | ||
@@ -332,3 +483,3 @@ } else { | ||
if (this.orientation == 'vertical' && touchOptimized) { | ||
if (touchOptimized) { | ||
navbarBottom.removeAttribute('hidden'); | ||
@@ -341,2 +492,12 @@ } else { | ||
} | ||
_blockAnimationUntilAfterNextRender() { | ||
this.setAttribute('no-anim', ''); | ||
afterNextRender(this, () => { | ||
this.removeAttribute('no-anim'); | ||
if (this._isShadyCSS()) { | ||
window.ShadyCSS.styleSubtree(this); | ||
} | ||
}); | ||
} | ||
} | ||
@@ -343,0 +504,0 @@ |
@@ -18,4 +18,5 @@ /** | ||
* ``` | ||
* <vaadin-drawer-toggle for="layout">Toggle drawer</vaadin-drawer-toggle> | ||
* <vaadin-drawer-layout id="layout"></vaadin-drawer-layout> | ||
* <vaadin-app-layout> | ||
* <vaadin-drawer-toggle slot="navbar">Toggle drawer</vaadin-drawer-toggle> | ||
* </vaadin-app-layout> | ||
* ``` | ||
@@ -54,3 +55,3 @@ * | ||
</slot> | ||
<button id="button" type="button"></button> | ||
<button id="button" type="button" aria-label\$="[[ariaLabel]]"></button> | ||
`; | ||
@@ -63,2 +64,8 @@ } | ||
static get properties() { | ||
return { | ||
ariaLabel: String | ||
}; | ||
} | ||
constructor() { | ||
@@ -65,0 +72,0 @@ super(); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
39159
616
0
15