Giter VIP home page Giter VIP logo

ember-attacher's Introduction

ember-attacher

npm version Download count all time npm Ember Observer Score GitHub CI

Compatibility


NOTE

The addon's dummy application needs a serious upgrade. I @tylerturdenpants have removed as much orf the support on flexi and flexi styles that I can, but the dummy app will still produces warnings regarding SASS division.

Additionally, this app likely has support beyond ember 3.24, but test fail locally since not all babel related issues during testing have been resolved.

As the only supporter of this addon, a father, and a full time employee at a software company, I really need the help to fully pull flexi out and to revamp the dummy app. Once these blockers are removed I can do the work to bring this addon into the future.


  • Ember.js v3.16 or above
  • Ember CLI v3.13 or above
  • Node.js v12 or above

Tooltips and popovers made easy. Just drop an <AttachTooltip/> or <AttachPopover/> in a parent and your floating element is ready to go!

<button>
  Click me

  <AttachTooltip>
    I'm a tooltip!
  </AttachTooltip>
</button>

<button class="other-button">
  No click me!

  <AttachPopover 
      @class='ember-attacher'
      @hideOn='click'
      @isShown={{true}}
      @showOn='click'
  >
    I'm a popover!
  </AttachPopover>
</button>

See the example site for a demonstration of all available options.

Installation

ember install ember-attacher

If you're upgrading from 1.x to 2.x see the upgrade guide.

Components

<AttachPopover/>

A popover attacher.

  • Has no default class or roles.
  • Does not modify the target in any way.
  • Adds aria-hidden attribute to the floating element

<AttachTooltip/>

A tooltip attacher. Subclass of <AttachPopover/>

  • Has the default class 'ember-attacher-floating ember-attacher-tooltip'

    • The default tooltip classes can be modified by altering the tooltipClass default. See here for details on editing default values.
  • Default role attribute of tooltip.

  • Causes the target to gain an aria-describedby attribute set to the tooltip's ID.

Options

Below is a list of all available options, along with their defaults.

{
  // The animation used to present the animation.
  // Options: ['fade', 'fill', 'none', 'perspective', 'scale', 'shift']
  animation: 'fill',

  // Whether or not an arrow will be displayed next to the attachment.
  arrow: false,
    
  // Add listeners that will automatically call an update function
  // Pass `true` to use the Floating UI default options or Options object to override them
  // Example: { ancestorScroll: false }
  // For more details see https://floating-ui.com/docs/autoUpdate 
  autoUpdate: false,

  // A class that will be applied to the attachment.
  class: null,

  // The flip priority of the attacment.
  // Space-delimited string, any combination of ['left', 'right', 'top', 'bottom']
  //
  // Example: 'left top bottom'
  flip: null,

  // The delay, in milliseconds, before the attachment will be hidden.
  hideDelay: 0,

  // The duration, in milliseconds, of the hide animation.
  hideDuration: 300,

  // Events that will cause the attachment to hide, typically in reference to the target.
  //
  // Space-delimited string, any combination of:
  // ['click', 'clickout', 'mouseleave blur escapekey']
  hideOn: 'mouseleave blur escapekey',

  // Interactive tooltips will not close when clicked or hovered over.
  interactive: false,

  // Set this to true if you have an interactive attachment that hides on mouseout and the
  // attachment is offset from its target. This should only be the case if you are using custom
  // CSS that offsets that attachment.
  isOffset: false,

  // Whether or not the attachment is initially shown.
  isShown: false,

  // If true, the attachment will only be inserted into the DOM on the first "show" trigger.
  // Useful for performance reasons, but will hide your attachment from search engines.
  lazyRender: false,

  // A middleware array that will be merged into computePosition options
  middleware: null,

  // A function to be fired when the attachment's visibility changes. The new visibility is passed
  // to the function as an arg.
  onChange: null,

  // The initial position of the attachment.
  // Options: ['left', 'right', 'top', 'bottom']
  placement: 'top',

  // The container where the attachment's DOM will be inserted.
  floatingElementContainer: '.ember-application',

  // An options object that will be passed to Floating UI "computePosition" function.
  floatingUiOptions: null,

  // NOT RECOMMENDED: We currently allow you to pass an explicit target, but this may be removed
  // in a future release.
  // Please provide your thoughts here: https://github.com/kybishop/ember-attacher/issues/109
  explicitTarget: null,

  // Whether or not to render the attachment in place in the DOM, as opposed to
  // on the floatingElementContainer. NOTE: Rendering in place can cause z-index issues.
  renderInPlace: false,

  // The delay, in milliseconds, before the attachment will be shown.
  showDelay: 0,

  // The duration, in milliseconds, of the show animation.
  showDuration: 300,

  // Events on the target that will cause the attachment to show. For performance reasons, we
  // recommend using some combination of 'mouseenter', 'focus', and 'click'
  showOn: 'mouseenter focus',

  // Whether to add event listeners for attachment show and hide in the capturing phase rather
  // than the bubbling phase. This should be set to true when there are elements on the page that
  // are stopping event propagation in the bubbling phase, and as a result preventing correct
  // showing and hiding of popovers and tooltips.
  useCapture: false,

  // The default padding if collision happens. Set "false" if no collision prevention needed 
  overflowPadding: 5 
}

User-defined defaults

User-defined defaults can be set in the consuming app or addon's config/environment.js. These defaults will be applied to every <AttachPopover/> and <AttachTooltip/>

// config/environment.js

module.exports = function(environment) {
  var ENV = {
    emberAttacher: {
      animation: 'shift',
      arrow: true
    }
  };
}

You can also set the user-defined defaults separately like so:

// config/environment.js

module.exports = function(environment) {
  var ENV = {
    emberAttacher: {
      tooltip: {
        animation: 'fade',
        arrow: true
      },
      popover: {
        animation: 'shift',
        arrow: false
      }
    }
  };
}

And finally you can do shared defaults along with user-defined separated defaults:

// config/environment.js

module.exports = function(environment) {
  var ENV = {
    emberAttacher: {
      showDuration: 300,
      hideDuration: 300,
      tooltip: {
        animation: 'fade',
        arrow: true
      },
      popover: {
        animation: 'shift',
        arrow: false
      }
    }
  };
}

The full list of editable defaults can be seen here.

Styles

ember-attacher provides styles for the default tooltip class, ember-attacher-tooltip, but no styles are included for {{attach-popover}}.

Example styling for a popover can be found in the dummy app. Note how the arrow must also be styled to match the popover (background color, size, etc.)

Testing

Use the isVisible() test helper to check if an attachment is visible.

import { click, find } from 'ember-native-dom-helpers';
import { isVisible } from 'ember-attacher';

test('example', async function(assert) {
  this.render(hbs`
    <button id="toggle">
      Click me, captain!

      <AttachPopover 
          @id='attachment'
          @hideOn='click'
          @showOn='click'
      >
        Click-toggled popover
      <AttachPopover/>
    </button>
  `);

  const attachment = find('#attachment');

  assert.equal(isVisible(attachment), false, 'Initially hidden');

  await click('#toggle');

  // You can also pass in a selector
  assert.equal(isVisible('#attachment'), true, 'Now shown');
});

Development setup

See the Contributing guide for details.

FAQ

How animations are implemented

Attachments are composed of two containers:

The outer container is positioned right next to the target via the CSS transform property. The inner container is required because animations also use transform, which would otherwise conflict with the container's position.

transform and tansition-duration are the CSS magic that allows animations to smoothly shift up/down, left/right, etc.

Note that animations require an implementation for each position (left, right, top, and bottom):

Credits

  • tippy.js, the library that inspired ember-attacher.

  • floating-ui, the library that powers positioning

  • ember-tooltips, the addon that influenced much of ember-attacher's API.

ember-attacher's People

Contributors

kybishop avatar dependabot-preview[bot] avatar tylerturdenpants avatar dependabot[bot] avatar robbiethewagner avatar ctjhoa avatar pzubar avatar jrjohnson avatar urbany avatar enkol avatar gcheung55 avatar kmccullough avatar richard-viney avatar krasnoukhov avatar duder-onomy avatar wagenet avatar scottwernervt avatar necojackarc avatar ember-tomster avatar endevea avatar mostafa-sakhiri avatar

Watchers

 avatar

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.