Giter VIP home page Giter VIP logo

iron-overlay-behavior's Introduction

Published on NPM Build status Published on webcomponents.org

IronOverlayBehavior

Use IronOverlayBehavior to implement an element that can be hidden or shown, and displays on top of other content. It includes an optional backdrop, and can be used to implement a variety of UI controls including dialogs and drop downs. Multiple overlays may be displayed at once.

See the demo source code for an example.

Closing and canceling

An overlay may be hidden by closing or canceling. The difference between close and cancel is user intent. Closing generally implies that the user acknowledged the content on the overlay. By default, it will cancel whenever the user taps outside it or presses the escape key. This behavior is configurable with the no-cancel-on-esc-key and the no-cancel-on-outside-click properties. close() should be called explicitly by the implementer when the user interacts with a control in the overlay element. When the dialog is canceled, the overlay fires an 'iron-overlay-canceled' event. Call preventDefault on this event to prevent the overlay from closing.

Positioning

By default the element is sized and positioned to fit and centered inside the window. You can position and size it manually using CSS. See Polymer.IronFitBehavior.

Backdrop

Set the with-backdrop attribute to display a backdrop behind the overlay. The backdrop is appended to <body> and is of type <iron-overlay-backdrop>. See its doc page for styling options.

In addition, with-backdrop will wrap the focus within the content in the light DOM. Override the _focusableNodes getter to achieve a different behavior. Additionally, you can add the iron-focusable attribute to any element in the light DOM to mark it as focusable.

Limitations

The element is styled to appear on top of other content by setting its z-index property. You must ensure no element has a stacking context with a higher z-index than its parent stacking context. You should place this element as a child of <body> whenever possible.

<iron-overlay-backdrop>

iron-overlay-backdrop is a backdrop used by Polymer.IronOverlayBehavior. It should be a singleton.

Styling

The following custom properties and mixins are available for styling.

Custom property Description Default
--iron-overlay-backdrop-background-color Backdrop background color #000
--iron-overlay-backdrop-opacity Backdrop opacity 0.6
--iron-overlay-backdrop Mixin applied to iron-overlay-backdrop. {}
--iron-overlay-backdrop-opened Mixin applied to iron-overlay-backdrop when it is displayed {}

See: Documentation, Demo.

Usage

Installation

npm install --save @polymer/iron-overlay-behavior

In a Polymer 3 element

import {PolymerElement, html} from '@polymer/polymer';
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
import {IronOverlayBehavior} from '@polymer/iron-overlay-behavior/iron-overlay-behavior.js';

class SampleElement extends mixinBehaviors(IronOverlayBehavior, PolymerElement) {
  static get template() {
    return html`
      <style>
        :host {
          background: white;
        }
      </style>
      <p>Overlay Content</p>
    `;
  }
}
customElements.define('sample-element', SampleElement);

Contributing

If you want to send a PR to this element, here are the instructions for running the tests and demo locally:

Installation

git clone https://github.com/PolymerElements/iron-overlay-behavior
cd iron-overlay-behavior
npm install
npm install -g polymer-cli

Running the demo locally

polymer serve --npm
open http://127.0.0.1:<port>/demo/

Running the tests

polymer test --npm

iron-overlay-behavior's People

Contributors

alirni avatar aomarks avatar atotic avatar bicknellr avatar blasten avatar camargo avatar cdata avatar danbeam avatar dependabot[bot] avatar dfreedm avatar e111077 avatar ebidel avatar garlicnation avatar jdbence avatar jklein24 avatar justinfagnani avatar keanulee avatar kevinwestern avatar limonte avatar linkenneth avatar mgiuffrida avatar naoak avatar notwaldorf avatar rictic avatar tedium-bot avatar tjsavage avatar tuct avatar valdrinkoshi avatar zinkkrysty avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iron-overlay-behavior's Issues

Iron Overlay type error on open in Chrome

I've recently seen a problem in Chrome on both Ubuntu and Mac OSX where opening an iron-overlay throws a Javascript error:

Uncaught TypeError: Cannot read property 'toString' of null

The full stack trace looks like:

obj.addEventListener    @   polydev/vendor/zone-microtask.js:973
Gestures.add    @   polymer.html:752 
Polymer.IronOverlayBehaviorImpl._toggleListener @   iron-overlay-behavior.html:268
(anonymous function)    @   iron-overlay-behavior.html:286
arguments.(anonymous function)  @   polydev/vendor/zone-microtask.js:406
(anonymous function)    @   polydev/vendor/zone-microtask.js:98
run @   polydev/vendor/zone-microtask.js:118
zoneBoundFn @   polydev/vendor/zone-microtask.js:91

I've seen this with both iron-dropdown and several custom elements I've used that mixin iron-overlay-behavior.

Tap causes type error to occur in firefox and safari

In firefox or safari using iron-overlay-behavior 1.0.7+ tapping outside the element causes a type error to occur in the handleNative fn. After some investigation it seems like ev.currentTarget is not the document node with __polymerGestures attached too which should of been assigned from a call to Polymer.Gestures.add within _toggleListeners when opened. Could this possibly be something todo with event forwarding? the correct node is wrapped up in __imp** not currentTarget.

z-index overrides are potentially fragile

Maybe this is a no-op, but if you override z-index of the overlay-backdrop using:

 --iron-overlay-backdrop: { z-index: 1000; }

Wont this throw off the z-index calculations in -manager which always starts at 10?

Iron overlays within iron overlays have multiple issues

Opening an iron overlay within another iron overlay has a few issues.

Firstly : When adding a backdrop, if you open a second overlay, the second backdrop has the wrong z-index, and when you close the second overlay, the background does not go away.

Opening the first overlay - note the backdrop z-index of 11.

overlay 1

Opening the second overlay. The backdrop does not have the right z-index (it's 9, when it should be higher than 11). Additionally, it does not have the 'opened' attribute.
overlay 2

On closing the second overlay backdrop 2 stays, and when then closing the first overlay, backdrop 1 disappears, but backdrop 2 stays on top of the page. Note how backdrop 1 (with z-index 11) has disappeared, but backdrop 2 with z-index 9 is still there.

overlay 3

Additionally, pressing escape with both overlays open closes both of them, when you would expect it to only close the one on top.

For our use case having overlays within a full page overlay makes sense, but it may be that they weren't designed to be layered in the first place?

with-backdrop changes should update backdropElement

When an iron-overlay-behavior element is open, changes to with-backdrop should update the backdropElement presence.

E.g.

<simple-overlay with-backdrop opened>
  Hello
</simple-overlay>
<script>
  setTimeout(function() {
    var overlay = document.querySelector('simple-overlay');
    overlay.withBackdrop = false; 
    // the backdrop element should have been closed
    console.log(overlay.backdropElement.opened); // should log false
  }, 1000);
</script>

position calculation triggered too early

iron-overlay-behavior triggers position calculation too early (or ready), resulting in a wrong/offsetted rendering of the element. Instead, this should be done on attached.

Capture focus for non 'withBackdrop' overlays not working

After installing 1.3.0, focus on iron-inputs in 'paper-dialog' stopped working. I cannot focus on any input after clicking anywhere else on the dialog or outside the dialog. Seems like this might be the breaking change a72f902 added a new listener for 'focus' but it is only handling it when having a dialog 'withBackdrop'. When I get rid of the listener the focus starts working just fine.

iron-overlay-behavior accessibility issues

Focus: focus state on this page is not very visible and should be revisited.

In general, this appears to be working fine with screen reader and keyboard navigation (testing just with Chrome / Mac / VoiceOver today as I don't have corp access on my Chromebook or Win machine remotely). Upon opening one of the overlays, I am able to navigate to the text / buttons within the overlay, but I can also navigate to the other options at the top of the page while the overlay is still open.

These overlays would seem more intuitive for screen reader users if focus stayed within them until the user took an action, e.g. activated one of the buttons or pressed escape. I don't think it should be possible to navigate to any of the background content before first closing out the dialogue. What are your thoughts? Is that not your intent here?

Also, we should consider making the titles of the overlays speak as announcements once open, so the user has better context about what just opened.

Error after component update.

I recently updated all my modules and this error is coming up. Not sure if it is a bug or something i am doing wrong.

Uncaught TypeError: Cannot read property 'toString' of nullobj.addEventListener @ polydev/vendor/zone-microtask.js:973Gestures.add @ polymer.html:673Polymer.IronOverlayBehaviorImpl._toggleListener @ iron-overlay-behavior.html:262(anonymous function) @ iron-overlay-behavior.html:280fnNames.map.forEach.global.zone.(anonymous function).arguments.(anonymous function) @ polydev/vendor/zone-microtask.js:406(anonymous function) @ polydev/vendor/zone-microtask.js:98run @ polydev/vendor/zone-microtask.js:118zoneBoundFn @ polydev/vendor/zone-microtask.js:91

Pass the original event to iron-overlay-canceled event

Expected

I can access the original event in iron-overlay-canceled to determine the

Actual

Not possible to access the original event

Long description

I used iron-overlay-behavior triggered by focusing/writing in an input field and wanted to avoid reopening the overlay when i focused the input again after clicking some stuff in the overlay.
(I try to implement a multiselect dropdown where the input is also used to search the options).

Only solution i found that allowed me to still use the close on click outside was to
add the original source event as detail to the iron-overlay-canceled event

(function() {

  Polymer({

    is: 'simple-overlay',

    behaviors: [
      Polymer.IronOverlayBehavior
    ],
    cancel:  function(event) {
      var cancelEvent = this.fire('iron-overlay-canceled', event, {cancelable: true});
      if (cancelEvent.defaultPrevented) {
        return;
      }

      this.opened = false;
      this._setCanceled(true);
    },
    _onCaptureClick:  function(event) {
      if (!this.noCancelOnOutsideClick &&
          this._manager.currentOverlay() === this &&
          Polymer.dom(event).path.indexOf(this) === -1) {
        this.cancel(event);
      }
    }

  });

})();

This allowed me to determine if the user clicked the input by adding a on-overlay-canceled function

<simple-overlay id="results" class="scrollable" on-iron-overlay-canceled="_checkOverlayCancle">
      _checkOverlayCancle: function (e){
        if(e.detail != null && 
          e.detail.srcElement != null &&
          e.detail.srcElement.classList.contains("tos-multiselect")){
          e.preventDefault();
          e.stopPropagation();
        }
      }

Loop in iron-overlay-manager

From @dsportes on June 14, 2015 12:15

I have a modal paper dialog opening a second modal paper-dialog.
This causes a loop (Maximum call stack exceed) in two different locations :
iron-overlay-manager.html line 63
paper-dialog-manager.htm line 210
I didn't find any workaround.
Regards

Copied from original issue: Polymer/polymer#1864

Mobile A11y Testing 11/1

ON Android with Talkback, upon opening these overlays, I receive no spoken feedback. This should speak out the title of the dialog as a spoken alert. Without seeing this visually, I have no idea that something is on the screen.

Also, once I open the Hello World overlay, I have no clear way to get out of it.

Once an overlay opens, like the scrolling one, it should steal focus. Right now, if I open it and continue swiping linearly, I just go to the next buttons and don't have access to the scrolling content.

Event to know when the dialog is canceled

I'd like to distinguish between a close and a cancel (from clicking outside the region).
Close happens to late, and I need to take action based on a cancel.

Firing iron-overlay-canceled would be ideal or even making canceled notify.

Opening from on-tap causes immediate close.

Basic scenario, have an item, which within its on-tap a non-modal paper-dialog, the overlay flashes up (sometimes slow enough to see) and then closes.

Using on-click it will appear, seems the handling of on-tap causes two events.

  <paper-item id="master" on-tap="tapMasterItem">{{currentLabel}}</paper-item>
    <paper-dialog id="menuDialog" with-backdrop="false">
      <paper-dialog-scrollable>
        <paper-menu selected="{{currentValue}}">
          <template as="dataitem" is="dom-repeat" items="{{items}}">
            <paper-item id="{{getValue(dataitem)}}" >{{getLabel(dataitem)}}</paper-item>
          </template>
        </paper-menu>
      </paper-dialog-scrollable>
    </paper-dialog>

    tapMasterItem: function(){
      if(!this.$.menuDialog.opened){
        this.$.menuDialog.open();
      }
    },

The backdrops of two different elements implementing iron-overlay-behavior are interfering

If two different elements are created, element-overlay-with-backdrop and element-overlay-with-backdrop2, both implement iron-overlay-behavior and both used with-backdrop, opening one after another and closing them, one overlay closes the other one's backdrop, and one backdrop doesn't close (is orphaned).

I have a suspicion that the manager is not working as it should - the current tests only cover the case where the overlays share the same backdrop - but once we introduce a different element which does not share (the backdrop is created on register event) - there are issues with correctly attributing backdrops and closing the right one.

prepareRenderOpened should call refit, not fit

Currently iron-overlay-behavior calls fit on opened (_prepareRenderOpened), and resetFit on close (_finishRenderClosed).
Instead, it should only call refit on _prepareRenderOpened, since the measuring of the dimensions matters in that moment, not when the overlay gets closed.

closingReason.canceled not set correctly after closing overlay 2nd time

If you open an overlay, then close it by clicking outside, the closingReason.canceled flag is set to true, all good so far. If you open the overlay again, then close it by clicking outside, the closingReason.canceled flag is set to false, and any listeners to iron-overlay-closed receive event.detail.canceled === false.

I think the problem is the cancel method in iron-overlay-behavior.html is setting opened to false before setting canceled to true. When I switched the lines within cancel, closingReason.canceled was set correctly and iron-overlay-closed listeners receive the proper canceled flag.

There is also a comma ending the first line in cancel, should probably be a semi-colon. Also wondering if this change should be made to the close method as well.

Lines in question: https://github.com/PolymerElements/iron-overlay-behavior/blob/master/iron-overlay-behavior.html#L213-L214
JSBin: http://jsbin.com/refogupana/1/edit?html,output

use requestAnimationFrame

It would improve performance to delay _onIronResize via requestAnimationFrame. e.g.

    // properties...
    _boundOnIronResize: {
        type: Function,
        value: function() {
          return requestAnimationFrame(this._onIronResize.bind(this));
        }
      }
    //...
    listeners: {
      'iron-resize': '_boundOnIronResize'
    },
    //...
    _onIronResize: function(){
       //can be overridden
    }

Same for _renderOpened/_renderClosed

iron-overlay-behavior does not properly scope styles

http://stackoverflow.com/questions/31199823/iron-overlay-behavior-styling-not-taking-effect

I have implemented the above component at http://polymer.zikes.me/bower_components/my-overlay/. You will see that changing the custom CSS variables do not have an effect on the backdrop.

I believe this is partly because the backdrop is created but not added to the parent component's scope. Adding the line this.scopeSubtree(this._backdrop); to the registered function of iron-overlay-behavior.html should resolve that, however the component's <style> and contents are still not copied into the parent document to apply those styles, and I do not know how to resolve that.

Multiple modal dialogs result in broken functionality

Looking through iron-overlay-manager.html, it looks like multiple overlays with backdrops are expected to work. It seems to be broken, though.

http://jsbin.com/taxoli/47/edit?html,output

In this example, the second overlay should have a backdrop, but the backdrop is still under the first. Looking at the source, it seems as if the backdrop is meant to move under the top-most dialog.

Other problems can occur when nesting overlays with backdrops. The backdrop is appended to the body, so it can't exist in the Z-space between the nested overlay element and its ancestor.

In dynamically created paper-dropdown-menu errored on click outside when opened [Solution]

Sometimes the path wouldn't be on Polymer.dom(event) because it returnes a node and event is CustomeEvent, thus it would give an error and not close the dropdown on click outside. The following code fixes the issue. please add it to the file.

_onCaptureClick: function(event) {
  var ev = Polymer.dom(event);
  if (!this.noCancelOnOutsideClick &&
    this._manager.currentOverlay() === this &&
    (
    (ev.path && ev.path.indexOf(this) === -1)
    ||(ev.node
      && ev.node.path
      && ev.node.path.indexOf(this) === -1)
    )) {
    this.cancel();
  }
},

Modal dialog not closing

From @pensierinmusica on August 7, 2015 14:46

Hi,

If the <paper-dialog> element has the attribute modal="true", the dialog does not close when the user clicks outside of the dialog area (as it properly does instead without modal="true").

The only interaction event that seems to close the dialog is the esc key (that, btw, is not available on mobile).

Any idea when this could be fixed? Thanks!

Copied from original issue: PolymerElements/paper-dialog#27

iron overlay behavior - comment syntax bug (very easy fix)

iron-overlay-behavior.html (line 19)
the behavior comment starts with /** instead of
this is causing a parsing issue on firefox, resulting the page to throw and error and ruin the page.

P.S. I caught the error while using polymer iron dropdown, the issue was causing the page to fail on calling the dropdowns to close on page load.

iron-overlay-closed event doc is garbled

https://elements.polymer-project.org/elements/iron-overlay-behavior#event-iron-overlay-closed

* @param {{canceled: (boolean|undefined)}} set to the `closingReason` attribute

Not sure exactly what this is supposed to look like. The description isn't really helpful.

I'm not sure whether the @param tag to an event should assume that the parameters are all passed in the detail object, or whether they may be added directly to the event object. (Maybe @garlicnation can help out here?)

In the first case, this should probably be:

* @param {boolean|undefined} cancelled Whether the overlay was cancelled.

In the latter case, I think it should be something like:

* @param {{canceled: (boolean|undefined)}} detail Set to the `closingReason` object.

Also, we really need to work on formatting those closure type definitions better in the output. They are fugly.

dialogs should restore focus to the previously focused element after closing

From @anthonytordillos on October 20, 2015 6:9

"the object with focus before the dialog box is opened should be saved. This will allow restoring focus to this element when the dialog box is closed."

Is this something paper-dialog-behavior can provide, or are consumers of the element required to handle it themselves?

http://www.w3.org/TR/wai-aria-practices/#modal_dialog

Copied from original issue: PolymerElements/paper-dialog-behavior#32

[Firefox] SyntaxError: unterminated comment

On line 41 in iron-overlay-behavior.html is a <body> tag that failes in Firefox.

Console log reports

SyntaxError: unterminated comment

The output of that file is

### Backdrop

Set the `with-backdrop` attribute to display a backdrop behind the overlay. The backdrop is
appended to `<body><script type='text/javascript' id="__bs_script__">//<![CDATA[
    document.write("<script async src='/browser-sync/browser-sync-client.2.7.7.js'><\/script>".replace("HOST", location.hostname));
//]]>
//# sourceURL=http://localhost:3000/bower_components/iron-overlay-behavior/iron-overlay-behavior.html.js

using paper-dropdown-menu inside a dialog will close it

it seems that there is another problem with the #64.

I've made you a JSBin

https://jsbin.com/lapedorogo/edit?html,console,output

I don't know why, but if you use paper-dropdown-menu + paper-menu + paper-item inside a dialog (dialog and paper-dropdown-menu are differents module), when selecting an item in the paper-dropdown-menu, an event will be fired which seems to be "iron-overlay-closed"

Update : no need to select an item, clicking outside to hide the list will have the same effect

Backdrop not removed after call to dialog.close() on a modal dialog shortly after open

I am not sure I understand issue #83 and this might be the same, but I suspect not. I also think it might have been introduced in a fairly recent change - because the code was working fairly recently. However I am not 100% sure of that as I have had to adjust timings of other things to handle a problem with theming. and it is possible that that change meant there are less things for the ajax request (see below) to queue behind.

It is a timing issue in that the dialog box that is opened and closed fairly rapidly. Let me try and explain ...

When I start up my application, I check for the existence of a cookie. If it doesn't exist I put up a modal dialog box to collect user credentials. The user clicks on an OK button it doesn't close the dialog box immediately, but rather sends an ajax request to the server to check credentials. Only if it passes these credentials the server sets the cookie (with an authentication token) and the dialog closes. This all works fine.

If the cookie exists, I briefly open a modal dialog box with a spinner in it. I then send an ajax request to the server to ask it to validate the user. Assuming it does, the Ajax response causes me to close the modal dialog box again.

Until recently this all worked fine. But over the past few days I have been experiencing a complete lock up of the user interface when the second case is true (ie we make this very quick Ajax call which causes me to open and then close the dialog rapidly). Putting the debugger on things I have been able to see that the overlay is still in place after I have closed the dialog. From the debugger, it reaches the close function of iron-overlay-backdrop.html, which attempts to set the this.opened flag to false. The _onTransitionend function is not called.

The flight time of my ajax request seems to be about 6 milliseconds.

I have now added a 200 millisecond delay before closing the dialog and it started working again.

Tabbing out of a modal dialog should stop focus event propagation

From @barakhub on August 30, 2015 4:15

paper-dialog-behavior provides modal behavior. If focus is set outside of the dialog, it's returned to somewhere within the dialog. In that case, the current focus handling should stop.

Example where this causes an issue:
http://poly-play.appspot.com/A5xo5E3I5iQ
(Follow the on-screen instructions to reproduce)

Here, if you try to tab out of the dialog, you can't (expected), but the next paper-button (outside of the dialog) is highlighted as it it has focus, since the focus event for it continued to propagate.

Copied from original issue: PolymerElements/paper-dialog-behavior#24

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.