From bf229cf9d268046d406f908e1f0ec23babb2c080 Mon Sep 17 00:00:00 2001
From: Markus Sanin
+ This component is pretty low lever and is intended to be a building block to
+ build your own components on top.
+
+ If you build something reusable that you think it's worth sharing you can
+ publish it as an addon so other can use it.
+ If so, let me know and I'll add it to this section. You can use the one below
+ as inspiration.
+ Ember Basic Dropdown can take a fair amount of configuration options on
+ invocations to alter its default behavior.
+
+ If you want all your dropdowns to behave on a certain way or have some certain
+ classes? Repeating the same options over and over on your templates is boring.
+
+ If you want to apply a configuration option to all your dropdowns there is no
+ special way or key in the
+
+ Inside your app's
+
+ That's all. No new concepts to learn, just your usual ember-cli work flow.
+
+ In this example the component is also named
+
+ Use the component without a trigger? Is that possible?
+
+ Yes, it is. You don't need to invoke the
+ Sometimes you just cannot achieve what you want with this approach, so you
+ need to step down and wire things yourself.
+
+ If you invoke the
+
+ What kind of things can you do with this?
+
+ By example, you can open or close the component when an item is clicked but
+ make the dropdown attach itself to an entirely different item in the page.
+
+ Let's create an input with a button. When that button is clicked the drodown
+ will open below the input, not not below the button that you clicked.
+
+ Remember that almost always you will want to use the provided trigger component
+
+ A good middle-ground is to apply the same trigger modifier that the component
+ uses, but to your element or component. It will get all of the same a11y and
+ bindings that the
+ Do you like animations in your dropdowns? Me too. Let's define some
+
+ It is that simple as create a CSS3 animation using the
+
+ You will probably also want to use
+
+ There is nothing else to know about animations, other that you have to use CSS
+ animations, not transitions.
+
+ The dropdown takes care of creating a clone when closing the dropdown so you
+ animation works in both directions.
+
+ It's hard to find a proper place in the guides for explaining every single
+ option in depth, and some of them are so straightforward that they don't
+ require an example, so use this section as a more exhaustive list.
+
+ All actions and subcomponents of Ember Basic Dropdown receive a single object
+ containing the entirety of the public API of the component.
+
+ Any non underscored property or action of this object can be considered public
+ and it's not going to suffed changes without causing a major version bump, so
+ if you are building another component on top of Ember Basic Dropdown, you know
+ that you are safe as long as you use this object.
+
+ Like the trigger, the dropdown accepts function to bind a few handy events.
+
+ Those events are just identical to the ones in the trigger.
+
+ Used in conjunction with the same events in the trigger it quite easy to make
+ a dropdown that opens when you hover the trigger and closes leave it, but
+ stays open if you move from the trigger to the content.
+
+ You can even delay the closing a bit to allow the users to briefly pass
+ outside the boundaries of the dropdown without closing it. Think the navbar of
+ your favourite social network:
+
+ Let's break this down.
+
+ First we
+
+ Then
+
+ If before that grace period they enter again the boundaries of the component,
+ we cancel the scheduled close. This would be much cleaner using
+
+ In the following chapters we will learn how to customize the dropdown
+ behaviour with all the different options.
+
+ In
+ a previous section
+ we already say that the dropdown bundles a few positioning strategies both
+ horizontally and vertically.
+
+ But you don't want to be limited to the positioning strategies I designed for
+ you. You might want the dropdown to float to the left of the trigger or
+ perhaps one inch south-west of it.
+
+ Fear not, my friend, the component has an escape valve for this. You can
+ design your own positioning function and pass it to the component. It just has
+ to fulfill a specific contract.
+
+ This function is the only thing you have to implement to tell the component
+ where it should be positioned.
+
+ The complete signature of the function is:
+
+ The return value of this function must also be an object with a specific
+ shape:
+
+ Sounds like a lot, but with an example you will see that it's not really hard.
+ Let's create a dropdown that opens to the right of the trigger, vertically
+ centered with it.
+
+ You can resize the window and scroll and you can see that the content stays
+ just where it should. It will even reposition automatically if the content
+ inside changes thanks to the magic of
+
+ The key concept that you need to extract is that all the machinery to position
+ the content and reposition when the content, scroll or screen changes is
+ handled by the dropdown, so the only missing piece you have to provide is the
+ function that calculates the cordinates.
+
+ If you disable the dropdown, it will not open or close by any mean, mouse,
+ keyboard or touch screen.
+
+ Note that being disabled does not prevent the dropdown or any of its
+ sub-components from firing events like
+
+ The component takes care by default of usual good practices, removing the
+
+ Although the top-level component is tagless, it does fire a few events that
+ you can use to react to changes in the state of the dropdown.
+
+ This has no mystery.
+
+ Pretty self-explanatory. The
+ What kinds of things you can do with this event?
+ In general when you want to do something outside the component when this
+ loads. By example, you can delay the loading of some data until the dropdown
+ is opened.
+
+ There is something you should know about this hook: If you
+
+ Let's use this feature along with the public API and event received as
+ aguments to do a nifty trick. We are going to iterate over the example above
+ so we prevent the component from opening, load the users and once loaded we
+ open it.
+ For the record, I don't think this is good UX
+ Symmetrically, you can perform on action when the dropdown is closed. For
+ example, save the a user selection, and you can also
+
+ Example: Create a dropdown with some checkboxes inside, and don't allow it to
+ close until one checkbox is selected.
+ Cruel, isn't it?
+ Those were the events fired by the top-level component, now let's go deep on
+ the events that are fired by the trigger.
+
+ This component is built with a technique known as
+ Contextual Components. If you haven't heard of it, check
+ the official guides
+ for some background.
+
+ The basic usage is pretty simple. There are no mandatory fields. Just invoke
+ the
+
+ Go, use it and inspect the DOM. I know it looks ugly, we'll style it later.
+
+ As you've inspected, the markup is very simple.
+
+ The
+
+ Out of the box the component already takes care of most things you need.
+
+ First of all, the component opens when you click on the trigger and closes
+ when you click anywhere else in the page. If you are reading this on a
+ smartphone you can also see that it opens when you tap on the trigger and it
+ already distinguishes proper taps from taps used for scrolling. The dropdown
+ is rendered not next to the trigger, but in a placeholder div in the root of
+ the application and positioned automatically with inline styles.
+
+ Lastly, if you inspect the DOM a second time you can see all the
+ a11y
+ machinery in place to make the component accesible. Even the trigger, despite
+ being a div, is focusable as it should be for a good keyboard experience. Also
+ if you have the trigger focus, you can open and close it with the enter or
+ space keys.
+
+ Now let's fix that terrible look. I'll give the dropdown a look and feel
+ inspired by dropdown buttons in bootstrap:
+
+ It just took a little bit of CSS. You could also have just assigned the right
+ classes and reused the styles from the framework (I can't demo that because I
+ don't have bootstrap here).
+
+ I want to stress that when it comes to CSS, the dropdown really doesn't care.
+ Let's make a material-like round button with a round content.
+
+ I got you.
+
+ And this is more or less everything you need to know about styles. Basically
+ there is none, so you can add create your own in CSS or reuse the classes that
+ CSS frameworks give you.
+
+ In the next section we will see the basic action hooks that this component
+ gives you to hook to events like opening and closing and many others.
+ I'm going to tell you the story of how this dropdown addon was born.
+ I was building a select component but I realized that a select is nothing more
+ than a dropdown with some extra stuff on top. And datepickers too. And
+ colorpickers, contextual menus and many other widgets.
+
+ Essentially, any floating box of content that is opened when you interact with
+ a trigger is basically a dropdown. Dropdowns are the foundation to at least
+ half a dozen common UI widgets we use daily, so I decided to shape this addon
+ in a way that was easy to reuse and customize to create those other widgets.
+
+ But if a dropdown is just a floating box activated by a trigger,
+ why would you want to use a third part addon for such a simple thing?
+
+ Well, there are two kinds of people. Those who think that dropdowns
+ are an easy thing and those who have actually built one.
+
+ When I transitioned from the first kind to the second I learned a lot of
+ stuff.
+
+ After I built the initial version, I started to build other widgets on top and
+ I had to step back a few times and identify where it wasn't flexible enough.
+ This process ended up in a component that distilled the essence of what a
+ dropdown is with as few assumptions as possible.
+
+ I honestly want to save you time and tears. I've been there.
+
+ This component is a
+ building block
+ for you to build other components on top, so it prioritizes flexibility and
+ explicitness over succinctness in its API, but still allows allows basic usage
+ out of the box with no ceremony.
+
+ Another thing to note is that this component doesn't have any theme by
+ default, so unless you do something about it, it will look pretty ugly. The
+ few styles it has are only to deal with positioning.
+ I hope you like it.
+ Ember-basic-dropdown is distributed as an
+ Ember CLI
+ addon, so the only thing you need to do to install it is run the following
+ command in your ember project directory
+
+ If you use just vanilla CSS, you're good to go. Ember-basic-dropdown will add
+ the default styles to your vendor css file.
+
+ However, if you are using SASS or LESS won't load any style by default.
+ Instead you need add an import statement to your styles explicitly.
+
+ The styles of the addon are
+ very minimal
+ and deal mostly with positioning. You can tweak a couple things but we'll get
+ to that later.
+
+ Now let's learn the API of the component.
+
+ By default the dropdown renders floating above the rest of your page but it
+ doesn't prevent the user from clicking on any other item. Overlays can fix
+ that and make dropdowns look cooler.
+
+ What do you have to know:
+
+ In the next section we'll talk more how to customize the styles.
+
+ The number one thing that you will want to customize in a dropdown is where
+ the floating content will be positioned in relation to the trigger.
+
+ Ember Basic Dropdown comes with a nice set of defaults. The rules are as
+ follow:
+ This sounds like a lot, but with an example it will be crystal clear.
+ In this example above I'm using the options
+
+ The default value for both options is
+ Narrow the window of the browser and play with scroll to see the automatic
+ positioning in action.
+ Although by default the component renders the content in the root of the app
+ and positions it absolutely, there are some situations where you want the
+ content to be
+ physically
+ next to the trigger.
+
+ To do so, pass
+
+ Please note that when rendering the content in place, the vertical position
+ will not automatically detect the best position based on the space around the
+ trigger. You have to explicitly pass
+
+ There is a few widgets in which the width of the floating box has to match the
+ width of the trigger design reasons. Since this is common enough, there is an
+ option to enable this behaviour.
+
+ In the section about
+ Custom Position
+ strategies we will see how to totally customize how the dropdown is positioned
+ by passing it a function. If you do so the options in this section will not
+ work unless your function, which will receive those options, honors them.
+
+ Since this component doesn't any visual theme, you can apply styles to it just
+ with plain CSS or even adding the classes your favourite CSS framework gives
+ you.
+
+ If don't use any css pre-processor this is all. If you do use SASS or LESS,
+ the addon will know it and will have to
+
+ There is only four variables you can tweak (Sass syntax)
+
+ If by example you want to change the colour of the overlay to be blue, you
+ could do this in your
+
+ In the next sections we'll give in more involved customizations.
+
+ Ember Basic Dropdown bundles some handy test helpers (
+ You can just have to import them at the top of your tests and call them
+ preceded by
+
+ Simulates a click to open or close the dropdown. As all integration test
+ helpers is already runloop aware, so you don't need to wrap it in
+
+ In case there is more than one dropdown rendered at the same time you can pass
+ a string with the scope to trigger it over the desired one.
+
+ Identical to
+
+ The trigger is the component in charge of opening and closing the dropdown
+ (although it also closes if you click outside it). By default the event that
+ to which the trigger reacts is the
+
+ You can change that passing the
+
+ This does not affect to the behavior of the dropdown on touch devices. On
+ mobile or tablets the dropdown automatically depends on the
+
+ As with any regular HTML element, you can attach events to the trigger using
+ the
+
+ What can you do with this? Let's see some examples.
+
+ One real world situation where I found this to be necessary, is when you want
+ to open the dropdown with a key that usually does not open it, like by example
+ the arrow keys.
+
+ As with any other event, calling
+
+ The
+
+ Good examples of this are preventing the component from opening with the mouse
+ and/or react in some way to those attempts.
+
+ Exactly identical to
+
+ I use this event to open the dropdown when you hover it and close it when you
+ leave but you can really use it a lot more.
+
+ By example, imagine that a dropdown is disabled and you want to highlight some
+ other element in the form that the user must enable first.
+
+ I've used this two events in conjuntion to style a parent element while some
+ of the components inside it have the focus, achieving a poor mans' version of
+ the upcoming CSS
+
+ This is the most involved example yet. Both the text input and the trigger are
+ focusable on their own, but by tracking when they get and loose the focus we
+ simulate that the entire input-group is focused, which would be impossible
+ just just CSS today.
+
+ Right now this behavior cannot be achieved across browsers without some help
+ from javascript.
+
+ Those are just some examples of the kind of behaviors you can implement adding
+ custom events to the trigger.
+
+ The Ember Power Project started with the goal of providing the Ember
+ ecosystem with a set of curated components that cover common UX needs,
+ built in Ember and designed work well in Ember apps., from following good
+ patterns like DDAU to also be test-friend and render property in Fastboot.
+
+ Over the time this evolved a bit into a theory of how an ecosystem should
+ shape it's addons: Basic components that compose to create more complex
+ components using good practices and allowing programmers to customize or
+ directly replace the parts they don't like.
+
+ Those components are divided in three tiers of complexity:
+ Helpers testing
+
+Addons
+
+System-wide config
+
+/config/environment.js
+ you need to learn. Just use The Ember Way™.
+/app/components
+ folder create a
+ ember-basic-dropdown.js
+ file:
+\{{basic-dropdown}}
+ but using this approach you can create many components with different names
+ that extend and customize the default one without modifying it.
+Usage without trigger
+
+<dropdown.trigger>
component to make the dropdown work. The yielded
+ dropdown
has actions you can invoke from any other item.
+ Yes, it is. You don't need to invoke the
+ <dropdown.trigger>
+ component to make the dropdown work. The yielded
+ dropdown
+ has actions you can invoke from any other item.
+open
+ or
+ toggle
+ action from say, a button, the dropdown is going to open and will take as the
+ element to be anchored to element with
+ data-ebd-id="\{{dropdown.uniqueId}}-trigger"
.
+<dropdown.trigger>
because it takes care of all the A11y,
+ bindings and classes for you, but when you can't it's good to know that you can
+ still use your own markup and wire things together yourself.
+<dropdown.trigger>
component gets.
+Animations
+
+ember-basic-dropdown--transitioning-in
,
+ ember-basic-dropdown--transitioned-in
+ and
+ ember-basic-dropdown--transitioning-out
+ classes that ember-basic-dropdown gives you automatically.
+.ember-basic-dropdown-content--below
+ and
+ .ember-basic-dropdown-content--above
+ to have different animations depending on where the dropdown is positioned.
+API reference
+
+
+Dropdown
+
+
+
+
+
+
+
+
+
+ Option
+ Type
+ Description
+
+
+ calculatePosition
+
+ Function
Fuction to customize how the content of the dropdown is positioned.
+
+
+ class
+
+ String
The class of the dropdown component. Since this component is tagless
+ by default, you need to combine it with the
+
+ tagName
+ to be effective
+
+ defaultClass
+
+ String
Another way of providing a class to the component without polluting
+ the
+
+ class
+ attribute. Useful in contextual component to allow users give their own
+ classes while still retaining some defaults
+
+ destination
+ String
+ The id of a DOM element where the dropdown will be rendered using
+
+ #-in-element
+
+ contentComponent
+
+ String or Component
The component to rended as content instead of the default content
+ component. You
+ probably
+ don't want to use this option.
+
+
+ horizontalPosition
+
+ String
The horizontal positioning strategy of the content. Can be one of
+
+ auto
+ (the default),
+ left
,
+ center
+ or
+ right
+
+ matchTriggerWidth
+
+ Boolean
(Default:
+
+ false
). Flag that indicates whether or not the content's
+ width should be equal to the width of the trigger.
+
+ preventScroll
+
+ Boolean
(Default:
+
+ false
). Flag that prevents any elements on the page outside
+ the dropdown from scrolling. This matches platform-provided
+ select
+ element behavior. Note that this has no effect when scroll is performed
+ on touch devic
+
+ renderInPlace
+
+ String
When passed
+
+ true
, the content will render next to the trigger instead
+ of being placed in the root of the body.
+
+ initiallyOpened
+
+ Boolean
(Default:
+
+ false
). When passed
+ true
+ the component is first rendered open. Used in combination with
+ preventScroll
+ it changes Fastboot user experience, but other than that it does not
+ alter its behavior. The user can close it as usual.
+
+ tagName
+
+ String
(Default:
+ ""
) The tag of the component.
+
+ triggerComponent
+
+ String
The component to rended as content instead of the default trigger
+ component.
+
+
+ verticalPosition
+
+ String
The vertical positioning strategy of the content. Can be one of
+
+ auto
+ (the default),
+ above
+ or
+ below
+
+ registerAPI
+
+ Function
An action that will be invoked with the new public API of the
+ component every time there is a change in the state of the component.
+
+
+ onOpen
+
+ Function
Action that will be called when the component is about to open.
+ Returning
+
+ false
+ from this function will prevent the component from being opened.
+
+
+onClose
+
+ Function
Action that will be called when the component is about to close.
+ Returning
+
+ false
+ from this function will prevent the component from being closed.Trigger
+
+
+
+
+
+
+
+
+
+ Option
+ Type
+ Description
+
+
+ ariaDescribedBy
+ String
+ Maps to
+ aria-described-by
+
+ ariaInvalid
+ Boolean
+ Maps to
+ aria-invalid
+
+ ariaLabel
+ String
+ Maps to
+ aria-label
+
+ ariaLabelledBy
+ String
+ Maps to
+ aria-labeledby
+
+ class
+ String
+ Extra classes to be added to the trigger components
+
+
+ tabindex
+ Number
+ Tabindex of the trigger, which defaults to 0 so the tigger is
+ focusable by default
+
+
+ htmlTag
+ String
+ (Default:
+ 'div'
) The tag of the trigger component
+
+ title
+ String
+ Maps to the
+ title
attribute
+
+ eventType
+ String
+ (Default:
+
+ 'click'
) The type of mouse event that triggers the trigger.
+ Valid values: "mousedown" and "click"
+
+
+stopPropagation
+ Boolean
+ (Default:
+
+ false
) Wether the trigger should prevent the propagation of
+ the event that triggers it (click or mousedown)Content
+
+
+
+
+
+
+
+
+
+ Option
+ Type
+ Description
+
+
+ class
+ String
+ The class of the dropdown's content
+
+
+ to
+ String
+ [DEPRECATED]The selector of a DOM element where the
+ dropdown will be rendered using ember-wormhole
+
+
+ animationEnabled
+ boolean
+ Flag to determine whether the content will allow CSS animations.
+ Defaults to true
+
+
+ htmlTag
+ String
+ (Default:
+ 'div'
) The tag of the content component
+
+
+shouldReposition
+ Function
+ An optional function that can be used to avoid uncecessary
+ repositions. To skip a reposition, simply return
+
+ false
. This function will be invoked when the DOM of the
+ content is changed. It receives two arguments: a
+ MutationRecord
+ and the public API object.Public API's methods and actions
+
+
+ { uniqueId: <string>, // Contains the unique of this instance of
+ EmberBasicDropdown. It's of the form `ember1234`. disabled: <boolean>,
+ // Truthy if the component received `disabled=true` isOpen: <boolean>,
+ // Truthy if the component is currently opened actions: { close() { ... }, //
+ Closes the dropdown open() { ... }, // Opens the dropdown reposition() { ...
+ }, // Repositions the dropdown toggle() { ... } // Toggles the dropdown } }
+
+
+Content events
+
+
+
+onFocusIn/onFocusOut(dropdown, event)
+
+onMouseEnter / onMouseLeave(dropdown, event)
<dd.Trigger \{{on "mousedown" this.prevent\\}}>
+ neglect mouse input: Open/close both by click and hover will trip our users.
+\{{on "mouseenter" (fn this.open dd)}}
+ and
+ \{{on "mouseleave" (fn this.closeLater dd)}}
+ open a close the dropdown, but we we leave we don't close immediately. Instead
+ we delay the close a few milliseconds as a grace period, allowing the user to
+ transition from the trigger to the content even if the trajectory of the mouse
+ is not perfect.
+ember-concurrency
+ tasks.
+Custom position
+
+
+
+calculatePosition
+ calculatePosition(trigger, content, destination, {
+ previousHorizontalPosition, horizontalPosition, previousVerticalPosition,
+ verticalPosition, matchTriggerWidth })
+
+
+
+
+trigger
: The DOM element of the trigger componentcontent
: The DOM element of the content componentdestination
: The DOM element where the content component is
+ going to be insertedpreviousHorizontalPosition
: The string with the horizontal
+ position the component had in the last time it was repositioned. If you
+ don't provide any or you pass
+ horizontalPosition="auto"
+ it will be
+ "left"
+ or
+ "right"
+ depending on the space around the triggerhorizontalPosition
: The string with the current horizontal
+ position. If you don't provide any or you pass
+ horizontalPosition="auto"
+ it will be
+ "left"
+ or
+ "right"
+ depending on the space around the triggerpreviousVerticalPosition
: The string with the vertical
+ position the component had in the last time it was repositioned. If you
+ don't provide any or you pass
+ verticalPosition="auto"
+ it will be
+ "left"
+ or
+ "right"
+ depending on the space around the triggerverticalPosition
: The string with the current vertical
+ position. If you don't provide any or you pass
+ verticalPosition="auto"
+ it will be
+ "above"
+ or
+ "below"
+ depending on the space around the triggermatchTriggerWidth
: Boolean that express the intention of the
+ developer to make the dropdown have the same width as the triggerrenderInPlace
: Boolean that express if the content will be
+ rendered in place. Useful since very usually the reposition logic must be
+ entirely different
+ { horizontalPosition, verticalPosition, style }
+
+
+
+horizontalPosition
: The new value of horizontalPositionverticalPosition
: The new value of verticalPositionstyle
: An object containing the CSS properties that will
+ position the object. It supports
+ top
,
+ left
,
+ right
+ and
+ width
MutationObservers
.
+Disabled
+
+onMouseEnter
.
+tabindex
+ of the trigger and set
+ [aria-disabled="true"]
+ to assist screen readers.
+Dropdown events
+
+
+
+onOpen(dropdown, event?)
dropdown
+ argument in the signature is the public API of the component. The
+ event
+ argument will be passed if this event is fired as a consequence of another
+ event (e.g. a click), but will be undefined if it was fired programmatically.
+return false;
+ from it you will prevent the component from opening.
+
+
+onClose(dropdown, event?)
return false
+ to prevent the component from closing.
+How to use it
+
+basic-dropdown
+ component which yields the public API to its block. That top-level component
+ has no markup, just pure behaviour. Once inside the block, the yielded API has
+ two contextual components on it that you can use:
+ trigger
+ and
+ content
.
+\{{dd.Trigger}}
+ component generates a simple div with some self-explainatory classes and
+ \{{dd.Content}}
+ doesn't render anything until you open the select.
+Overview
+
+
+
+
+Installation
+
+
+
+
+ $ ember install ember-basic-dropdown
+
+
+
+Overlays
+
+
+
+
+$ember-basic-dropdown-overlay-background
+ SASS variable or target the
+ .ember-basic-dropdown-overlay
+ pointer-events: none
, so it is transparent to clicks but you
+ can change that using the
+ $ember-basic-dropdown-overlay-pointer-events
+ SASS variable or target the same class.
+ Position
+
+
+
+horizontalPosition / verticalPosition
+
+
+<dd.Content>
+ has not pre-defined size, so it will adapt to the size its childs.
+ verticalPosition
+ and
+ horizontalPosition
+ to override the default behaviour.
+auto
, but you can pass
+ verticalPosition=above|below
+ and
+ horizontalPosition=auto-right|right|center|left
.
+
+
+renderInPlace
renderInPlace=true
+ to the component. Inspect the DOM of the next example to see the difference.
+verticalPosition="above"
+ to render it over the trigger.
+
+
+matchTriggerWidth
Styles
+
+@import
+ the styles explicitly. This gives you the chance to set a few variables that
+ Ember Basic Dropdown will use.
+app.scss
/app.less
.
+Test helpers
+
+
+
+clickDropdown
+ and
+ tapDropdown
) that make it easier to simulate user interaction in
+ acceptance tests.
+await
.
+
+
+clickTrigger(scope = null, eventOptions)
Ember.run
.
+
+
+tapTrigger(scope = null, eventOptions)
clickTrigger
+ but simulates a tap instead.
+Trigger events
+
+click
+ event.
+eventType="mousedown"
+ to the trigger. Check below for both approaches. The difference is subtle.
+"touchend"
+ event.
+Event handlers
+
+\{{on}}
+ element modifier. The events you subscribe to using this approach will aways
+ run before the default events that this component attaches, giving you a
+ chance to prevent the default behavior by calling
+ event.stopImmediatePropagation()
.
+
+
+\{{on "keydown"}}
e.stopImmediatePropagation()
+ will stop the default handler from running, so you can use this action to
+ prevent the
+ space,
+ enter
+ and
+ esc
+ keys from doing what they do by default.
+
+
+\{{on "click"}}
click
+ event is the one that usually opens the dropdown, but you can pass your own
+ function.
+
+
+\{{on "touchend"}}
\{{on "click"}}
+ but for touch screens. I'm not even going to create another example.
+
+
+\{{on "mouseenter"}} / \{{on "mouseleave"}}
+
+\{{on "focus"}}/\{{on "blur"}}
:focus-within
+ pseudo selector.
+
+ The basic dropdown that your
+
+ needs
+
+Ready to go
+ Prepared out of the box with a minimum set of defaults that let you drop
+ it into your app, style it to your taste and not worry about the little
+ details.
+ With Ember for Ember
+ Built on top of other ember addons, it provides an API based on contextual
+ components that feels natural to use and style.
+ Low level primitives
+ Designed as a building block for your own components, it has no styles and
+ makes no assumptions. It gives you the right primitives to taylor your
+ perfect widget.
+ Support the Ember Power Project
+
+
+
+
+ By creating a network if addons that compose between them to create even + more addons, we share more. The more we share, the smaller our apps become + because we don't need to reinvent wheels. +
+ ++ If you enjoy the addons this project provides and they help you in your + daily work, you can support the development of the addons and it's + documentation pages with a any contribution you feel appropiate by + clicking on the button below but above all, by contributing, opening + issues and Pull Requests, answering questions in Slack or StackOverflow + and above all, showing appreciation for everyone who works on the Open + Source Software we all use everyday. +
+ + + ++ Thank you! +
+ + \ No newline at end of file diff --git a/docs/app/templates/scrolling-container.hbs b/docs/app/templates/scrolling-container.hbs new file mode 100644 index 00000000..d3071ad6 --- /dev/null +++ b/docs/app/templates/scrolling-container.hbs @@ -0,0 +1,17 @@ +
+ What if your app doesn't scroll on the body tag? You can have the dropdown
+ render wherever you would like. If you render it on an element inside the
+ block that is scrolling the dropdown will automatically scroll with your
+ trigger. You need to give the target element
+ position: relative;
+ for the dropdown to be positioned properly.
+