ember-power-select
Advanced tools
Comparing version 0.1.8 to 0.2.0
@@ -32,7 +32,6 @@ import Ember from 'ember'; | ||
layout: layout, | ||
opened: false, | ||
disabled: false, | ||
searchEnabled: true, | ||
searchPlaceholder: null, | ||
dropdownPosition: 'auto', // auto | above | below | ||
classNames: ['ember-power-select-wrapper'], | ||
loadingMessage: "Loading options...", | ||
@@ -43,24 +42,8 @@ noMatchesMessage: "No results found", | ||
attributeBindings: ['dir'], | ||
classNames: ['ember-power-select'], | ||
classNameBindings: ['_opened:opened', 'disabled', 'multiple', 'renderInPlace', '_dropdownPositionClass'], | ||
_highlighted: null, | ||
_searchText: '', | ||
_loadingOptions: false, | ||
_wormholeDestination: (Ember.testing ? 'ember-testing' : 'ember-power-select-wormhole'), | ||
matcher: (value, text) => text === '' || stripDiacritics(value).toUpperCase().indexOf(stripDiacritics(text).toUpperCase()) > -1, | ||
// Lifecycle hooks | ||
init(){ | ||
this._super(...arguments); | ||
const self = this; | ||
const rootSelector = Ember.testing ? '#ember-testing' : this.container.lookup('application:main').rootElement; | ||
this.appRoot = document.querySelector(rootSelector); | ||
this.handleRootClick = function handleRootClick(e) { | ||
if (!self.element.contains(e.target)) { self.close(); } | ||
}; | ||
this.handleRepositioningEvent = function handleRepositioningEvent(/* e */) { | ||
run.throttle(self, 'repositionDropdown', 60, true); | ||
}; | ||
}, | ||
didReceiveAttrs({ newAttrs: { options, multiple } }) { | ||
@@ -76,10 +59,9 @@ if (multiple) { | ||
willDestroy() { | ||
this._super(...arguments); | ||
this.removeGlobalEvents(); | ||
}, | ||
// CPs | ||
_notLoadingOptions: computed.not('_loadingOptions'), | ||
dropdownClasses: computed('multiple', function() { | ||
return `ember-power-select ${this.get('multiple') && 'multiple'}`; | ||
}), | ||
selectedOption: computed('selected', { | ||
@@ -98,6 +80,2 @@ get() { | ||
tabindex: computed('disabled', function() { | ||
return !this.get('disabled') ? "0" : "-1"; | ||
}), | ||
triggerMultipleInputStyle: computed('_searchText', function() { | ||
@@ -113,21 +91,6 @@ return htmlSafe(`width: ${(this.get('_searchText.length') || 0) * 0.5 + 2}em`); | ||
actions: { | ||
toggle(/* e */){ | ||
if (this.get('_opened')) { | ||
this.close(); | ||
this.focusTrigger(); | ||
} else { | ||
this.open(); | ||
} | ||
}, | ||
select(option, e) { | ||
select(option, toggleDropdown, e) { | ||
e.preventDefault(); | ||
if (this.get('multiple')) { | ||
this.addOrRemoveToSelected(option); | ||
} else if (this.get('selectedOption') !== option) { | ||
this.set('selectedOption', option); | ||
} | ||
if (this.get('onchange')) { this.get('onchange')(this.get('selectedOption')); } | ||
this.close(); | ||
this.focusTrigger(); | ||
this.select(option); | ||
toggleDropdown(e); | ||
}, | ||
@@ -142,6 +105,3 @@ | ||
e.stopPropagation(); | ||
this.get('selectedOption').removeObject(option); | ||
this._resultsDirty = true; | ||
if (this.get('onchange')) { this.get('onchange')(this.get('selectedOption')); } | ||
run.scheduleOnce('afterRender', this, this.repositionDropdown); | ||
this.removeOption(option); | ||
}, | ||
@@ -166,15 +126,39 @@ | ||
keydown(e) { | ||
searchKeydown(toggleDropdown, e) { | ||
if (e.keyCode === 40 || e.keyCode === 38) { // Arrow up/down | ||
this.handleVerticalArrowKey(e); | ||
} else if (e.keyCode === 13) { // Enter | ||
this.handleEnter(e); | ||
this.pressedEnterOnSeach(e); | ||
toggleDropdown(e); | ||
} else if (e.keyCode === 9) { // Tab | ||
this.handleTab(e); | ||
toggleDropdown(); | ||
} else if (e.keyCode === 27) { // escape | ||
this.close(); | ||
this.focusTrigger(); | ||
e.preventDefault(); | ||
toggleDropdown(e); | ||
} else if (e.keyCode === 8) { // backspace | ||
this.handleBackspace(e); | ||
} | ||
}, | ||
multipleModeInputKeydown(e) { | ||
if (e.keyCode === 40 || e.keyCode === 38) { // Arrow up/down | ||
return this.handleVerticalArrowKey(e); | ||
} | ||
let event = document.createEvent('Event'); | ||
if (e.keyCode === 8) { // backspace | ||
this.removeLastOptionIfSearchIsEmpty(); | ||
event.initEvent('dropdown:open', true, true); | ||
} else if (e.keyCode === 13) { // Enter | ||
e.stopPropagation(); | ||
this.pressedEnterOnMultipleSelect(); | ||
event.initEvent('dropdown:toggle', true, true); | ||
} else if (e.keyCode === 9) { // Tab | ||
event.initEvent('dropdown:close', true, true); | ||
} else if (e.keyCode === 27) { // escape | ||
e.preventDefault(); | ||
event.initEvent('dropdown:close', true, true); | ||
} else { | ||
event.initEvent('dropdown:open', true, true); | ||
} | ||
this.element.querySelector('.ember-power-select').dispatchEvent(event); | ||
} | ||
@@ -184,20 +168,3 @@ }, | ||
// Methods | ||
close() { | ||
this.set('_opened', false); | ||
this.set('_searchText', ''); | ||
this.set('_dropdownPositionClass', null); | ||
this.removeGlobalEvents(); | ||
}, | ||
focusTrigger() { | ||
this.element.querySelector(`.ember-power-select-trigger${this.get('multiple') ? '-multiple-input' : ''}`).focus(); | ||
}, | ||
open() { | ||
if (this.get('disabled')) { return; } | ||
this.set('_opened', true); | ||
const pos = this.get('dropdownPosition'); | ||
const renderInPlace = this.get('renderInPlace'); | ||
this.set('_dropdownPositionClass', renderInPlace ? 'below' : (pos === 'auto' ? null : pos)); | ||
this.addGlobalEvents(); | ||
onOpen() { | ||
if (this._resultsDirty) { this.refreshResults(); } | ||
@@ -209,3 +176,2 @@ if (this.get('multiple')) { | ||
} | ||
run.scheduleOnce('afterRender', this, this.repositionDropdown); | ||
run.scheduleOnce('afterRender', this, this.focusSearch); | ||
@@ -215,33 +181,33 @@ run.scheduleOnce('afterRender', this, this.scrollIfHighlightedIsOutOfViewport); | ||
swallowEvent(e) { | ||
e.stopPropagation(); | ||
onClose() { | ||
this.set('_searchText', ''); | ||
this.set('_highlighted', null); | ||
this._resultsDirty = true; | ||
}, | ||
handleEnter(e) { | ||
if (this.get('disabled')) { return; } | ||
if (this.get('_opened')) { | ||
const highlighted = this.get('_highlighted'); | ||
if (this.get('multiple')) { | ||
if ((this.get('selected') || []).indexOf(highlighted) === -1) { | ||
this.send('select', highlighted, e); | ||
} else { | ||
this.close(); | ||
} | ||
} else { | ||
this.send('select', highlighted, e); | ||
} | ||
} else { | ||
this.send('toggle', e); | ||
onFocus() { | ||
if (this.get('multiple')) { this.focusSearch(); } | ||
}, | ||
select(option) { | ||
if (this.get('multiple')) { | ||
this.addOrRemoveToSelected(option); | ||
} else if (this.get('selectedOption') !== option) { | ||
this.set('selectedOption', option); | ||
} | ||
if (this.get('onchange')) { this.get('onchange')(this.get('selectedOption')); } | ||
}, | ||
handleTab(e) { | ||
if (this.get('_opened')) { | ||
e.preventDefault(); | ||
this.close(); | ||
this.focusTrigger(); | ||
pressedEnterOnSeach() { | ||
const highlighted = this.get('_highlighted'); | ||
this.select(highlighted); | ||
}, | ||
pressedEnterOnMultipleSelect() { | ||
const highlighted = this.get('_highlighted'); | ||
if (highlighted && (this.get('selected') || []).indexOf(highlighted) === -1) { | ||
this.select(highlighted); | ||
} | ||
}, | ||
handleVerticalArrowKey(e) { | ||
@@ -254,3 +220,3 @@ e.preventDefault(); | ||
handleBackspace(e) { | ||
removeLastOptionIfSearchIsEmpty() { | ||
if (!this.get('multiple')) { return; } | ||
@@ -260,3 +226,3 @@ if (this.get('_searchText.length') !== 0) { return; } | ||
if (!lastSelection) { return; } | ||
this.send('removeOption', lastSelection, e); | ||
this.removeOption(lastSelection); | ||
if (typeof lastSelection === 'string') { | ||
@@ -268,5 +234,10 @@ this.set('_searchText', lastSelection); // TODO: Convert last selection to text | ||
} | ||
this.open(); | ||
}, | ||
removeOption(option) { | ||
this.get('selectedOption').removeObject(option); | ||
this._resultsDirty = true; | ||
if (this.get('onchange')) { this.get('onchange')(this.get('selectedOption')); } | ||
}, | ||
addOrRemoveToSelected(option) { | ||
@@ -294,7 +265,5 @@ if (this.get('selectedOption').contains(option)) { | ||
focusSearch() { | ||
if (this.get('searchEnabled')) { | ||
this.appRoot.querySelector('.ember-power-select-search input').focus(); | ||
} else if (this.get('multiple')) { | ||
this.element.querySelector('.ember-power-select-trigger-multiple-input').focus(); | ||
} | ||
const searchInput = document.querySelector('.ember-power-select-search input') || | ||
this.element.querySelector('.ember-power-select-trigger-multiple-input'); | ||
if (searchInput) { searchInput.focus(); } | ||
}, | ||
@@ -320,35 +289,2 @@ | ||
repositionDropdown() { | ||
if (this.get('renderInPlace')) { return; } | ||
const dropdownPositionStrategy = this.get('dropdownPosition'); | ||
const dropdown = this.appRoot.querySelector('.ember-power-select-dropdown'); | ||
const width = this.element.offsetWidth; | ||
let left = this.element.offsetLeft; | ||
dropdown.style.width = `${width}px`; | ||
let top; | ||
if (dropdownPositionStrategy === 'above') { | ||
top = this.element.offsetTop - dropdown.offsetHeight; | ||
} else if (dropdownPositionStrategy === 'below') { | ||
top = this.element.offsetTop + this.element.offsetHeight; | ||
} else { // auto | ||
const viewportTop = document.body.scrollTop; | ||
const viewportBottom = window.scrollY + window.innerHeight; | ||
const dropdownHeight = dropdown.offsetHeight; | ||
const selectTop = this.element.offsetTop; | ||
const enoughRoomBelow = selectTop + this.element.offsetHeight + dropdownHeight < viewportBottom; | ||
const enoughRoomAbove = selectTop - viewportTop > dropdownHeight; | ||
let positionClass = this.get('_dropdownPositionClass'); | ||
if (positionClass === 'below' && !enoughRoomBelow && enoughRoomAbove) { | ||
positionClass = this.set('_dropdownPositionClass', 'above'); | ||
} else if (positionClass === 'above' && !enoughRoomAbove && enoughRoomBelow) { | ||
positionClass = this.set('_dropdownPositionClass', 'below'); | ||
} else if (!positionClass) { | ||
positionClass = this.set('_dropdownPositionClass', enoughRoomBelow ? 'below' : 'above'); | ||
} | ||
top = selectTop + (positionClass === 'below' ? this.element.offsetHeight : -dropdownHeight); | ||
} | ||
dropdown.style.top = `${top}px`; | ||
dropdown.style.left = `${left}px`; | ||
}, | ||
refreshResults() { | ||
@@ -364,3 +300,2 @@ const { _options: options, _searchText: searchText } = this.getProperties('_options', '_searchText'); | ||
this._resultsDirty = false; | ||
run.scheduleOnce('afterRender', this, this.repositionDropdown); | ||
}, | ||
@@ -370,7 +305,3 @@ | ||
this.set('_options', options); | ||
if (this.get('_opened')) { | ||
this.refreshResults(); | ||
} else { | ||
this._resultsDirty = true; | ||
} | ||
this.refreshResults(); | ||
}, | ||
@@ -390,17 +321,3 @@ | ||
}); | ||
}, | ||
addGlobalEvents() { | ||
this.appRoot.addEventListener('click', this.handleRootClick); | ||
window.addEventListener('scroll', this.handleRepositioningEvent); | ||
window.addEventListener('resize', this.handleRepositioningEvent); | ||
window.addEventListener('orientationchange', this.handleRepositioningEvent); | ||
}, | ||
removeGlobalEvents() { | ||
this.appRoot.removeEventListener('click', this.handleRootClick); | ||
window.removeEventListener('scroll', this.handleRepositioningEvent); | ||
window.removeEventListener('resize', this.handleRepositioningEvent); | ||
window.removeEventListener('orientationchange', this.handleRepositioningEvent); | ||
} | ||
}); |
@@ -9,4 +9,7 @@ /* global require, module */ | ||
var buf = fs.readFileSync(inputFile, "utf8"); | ||
var result = sass.renderSync({ data: buf }); | ||
var result = sass.renderSync({ | ||
data: buf, | ||
includePaths: ['node_modules/ember-basic-dropdown/app/styles/'] | ||
}); | ||
fs.writeFileSync(outputFile, result.css); |
@@ -8,2 +8,11 @@ module.exports = { | ||
{ | ||
name: 'ember 1.13', | ||
dependencies: { | ||
'ember': '1.13.8' | ||
}, | ||
resolutions: { | ||
'ember': '1.13.8' | ||
} | ||
}, | ||
{ | ||
name: 'ember-release', | ||
@@ -10,0 +19,0 @@ dependencies: { |
@@ -8,8 +8,2 @@ /* jshint node: true */ | ||
name: 'ember-power-select', | ||
contentFor: function(type, config) { | ||
if (config.environment !== 'test' && type === 'body-footer') { | ||
return '<div id="ember-power-select-wormhole"></div>'; | ||
} | ||
}, | ||
included: function(app) { | ||
@@ -16,0 +10,0 @@ // Don't include the precompiled css file if the user uses ember-cli-sass |
{ | ||
"name": "ember-power-select", | ||
"version": "0.1.8", | ||
"version": "0.2.0", | ||
"description": "The default blueprint for ember-cli addons.", | ||
@@ -61,3 +61,3 @@ "homepage": "http://www.ember-power-select.com", | ||
"ember-cli-htmlbars": "0.7.9", | ||
"ember-wormhole": "0.3.4" | ||
"ember-basic-dropdown": "0.1.2" | ||
}, | ||
@@ -64,0 +64,0 @@ "ember-addon": { |
[![Build Status](https://travis-ci.org/cibernox/ember-power-select.svg?branch=master)](https://travis-ci.org/cibernox/ember-power-select) | ||
# Ember-power-select | ||
# Ember-Power-Select | ||
I was tired of reinventing select components because other options were not easy to customized, | ||
so I decided to built one. | ||
Ember Power Select is an Ember-first select component modeled after [Select2](https://select2.github.io/). | ||
Based in select2.js, but built from scratch, 100% in ember. | ||
**Disclaimer**: This component is in its first days of life. Although I don't expect the public API | ||
to suffer significant changes be aware creating your own component that extends from this is not adviced | ||
**Disclaimer**: This component is in a very early alpha stage. Although the public API is not expected | ||
to suffer significant changes, be aware that creating your own component that extends from this is not advised | ||
yet. | ||
You can check the full documentation in [www.ember-power-select.com](http://www.ember-power-select.com) | ||
You can check the full documentation at [www.ember-power-select.com](http://www.ember-power-select.com) | ||
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
38
50482
1472
13
+ Addedember-basic-dropdown@0.1.2
+ Addedember-basic-dropdown@0.1.2(transitive)
- Removedember-wormhole@0.3.4