344 lines
10 KiB
JavaScript
344 lines
10 KiB
JavaScript
import _Promise from 'babel-runtime/core-js/promise';
|
|
import _setImmediate from 'babel-runtime/core-js/set-immediate';
|
|
import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
|
|
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
|
import _createClass from 'babel-runtime/helpers/createClass';
|
|
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
|
import _inherits from 'babel-runtime/helpers/inherits';
|
|
/*
|
|
Copyright 2013-2015 ASIAL CORPORATION
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
import onsElements from '../ons/elements';
|
|
import util from '../ons/util';
|
|
import autoStyle from '../ons/autostyle';
|
|
import ModifierUtil from '../ons/internal/modifier-util';
|
|
import BaseElement from './base/base-element';
|
|
import contentReady from '../ons/content-ready';
|
|
|
|
var defaultClassName = 'segment';
|
|
var scheme = {
|
|
'': 'segment--*',
|
|
'.segment__item': 'segment--*__item',
|
|
'.segment__input': 'segment--*__input',
|
|
'.segment__button': 'segment--*__button'
|
|
};
|
|
|
|
var generateId = function () {
|
|
var i = 0;
|
|
return function () {
|
|
return 'ons-segment-gen-' + i++;
|
|
};
|
|
}();
|
|
|
|
/**
|
|
* @element ons-segment
|
|
* @category control
|
|
* @modifier material
|
|
* [en]Material Design segment[/en]
|
|
* [ja][/ja]
|
|
* @description
|
|
* [en]
|
|
* Segment component. Use this component to have a button bar with automatic styles that switch on click of another button.
|
|
*
|
|
* Will automatically display as a Material Design segment on Android.
|
|
* [/en]
|
|
* [ja][/ja]
|
|
* @codepen hLayx
|
|
* @tutorial vanilla/Reference/segment
|
|
* @guide theming.html#modifiers [en]More details about the `modifier` attribute[/en][ja]modifier属性の使い方[/ja]
|
|
* @guide theming.html#cross-platform-styling-autostyling [en]Information about cross platform styling[/en][ja]Information about cross platform styling[/ja]
|
|
* @example
|
|
* <ons-segment>
|
|
* <ons-button>Label 1</ons-button>
|
|
* <ons-button>Label 2</ons-button>
|
|
* <ons-button>Label 3</ons-button>
|
|
* </ons-segment>
|
|
*/
|
|
|
|
var SegmentElement = function (_BaseElement) {
|
|
_inherits(SegmentElement, _BaseElement);
|
|
|
|
/**
|
|
* @event postchange
|
|
* @description
|
|
* [en]Fires after the active button is changed.[/en]
|
|
* [ja][/ja]
|
|
* @param {Object} event
|
|
* [en]Event object.[/en]
|
|
* [ja][/ja]
|
|
* @param {Number} event.index
|
|
* [en]Tapped button index.[/en]
|
|
* [ja][/ja]
|
|
* @param {Object} event.segmentItem
|
|
* [en]Segment item object.[/en]
|
|
* [ja][/ja]
|
|
*/
|
|
|
|
/**
|
|
* @attribute modifier
|
|
* @type {String}
|
|
* @description
|
|
* [en]The appearance of the segment.[/en]
|
|
* [ja][/ja]
|
|
*/
|
|
|
|
/**
|
|
* @attribute tabbar-id
|
|
* @initonly
|
|
* @type {String}
|
|
* @description
|
|
* [en]ID of the tabbar element to "connect" to the segment. Must be inside the same page.[/en]
|
|
* [ja][/ja]
|
|
*/
|
|
|
|
/**
|
|
* @attribute active-index
|
|
* @initonly
|
|
* @default 0
|
|
* @type {Number}
|
|
* @description
|
|
* [en]Index of the first active button, only works if there is no connected tabbar (in which case the active tab sets the active button).[/en]
|
|
* [ja][/ja]
|
|
*/
|
|
|
|
/**
|
|
* @attribute disabled
|
|
* @description
|
|
* [en]Specify if segment should be disabled.[/en]
|
|
* [ja]ボタンを無効化する場合は指定します。[/ja]
|
|
*/
|
|
|
|
function SegmentElement() {
|
|
_classCallCheck(this, SegmentElement);
|
|
|
|
var _this = _possibleConstructorReturn(this, (SegmentElement.__proto__ || _Object$getPrototypeOf(SegmentElement)).call(this));
|
|
|
|
_this._segmentId = generateId();
|
|
_this._tabbar = null;
|
|
_this._onChange = _this._onChange.bind(_this);
|
|
_this._onTabbarPreChange = _this._onTabbarPreChange.bind(_this);
|
|
|
|
contentReady(_this, function () {
|
|
_this._compile();
|
|
_setImmediate(function () {
|
|
return _this._lastActiveIndex = _this._tabbar ? _this._tabbar.getActiveTabIndex() : _this.getActiveButtonIndex();
|
|
});
|
|
});
|
|
return _this;
|
|
}
|
|
|
|
_createClass(SegmentElement, [{
|
|
key: '_compile',
|
|
value: function _compile() {
|
|
autoStyle.prepare(this);
|
|
this.classList.add(defaultClassName);
|
|
|
|
for (var index = this.children.length - 1; index >= 0; index--) {
|
|
var item = this.children[index];
|
|
item.classList.add('segment__item');
|
|
|
|
var input = util.findChild(item, '.segment__input') || util.create('input.segment__input');
|
|
input.type = 'radio';
|
|
input.value = index;
|
|
input.name = input.name || this._segmentId;
|
|
input.checked = !this.hasAttribute('tabbar-id') && index === (parseInt(this.getAttribute('active-index')) || 0);
|
|
|
|
var button = util.findChild(item, '.segment__button') || util.create('.segment__button');
|
|
if (button.parentElement !== item) {
|
|
while (item.firstChild) {
|
|
button.appendChild(item.firstChild);
|
|
}
|
|
}
|
|
|
|
item.appendChild(input);
|
|
item.appendChild(button);
|
|
}
|
|
|
|
ModifierUtil.initModifier(this, scheme);
|
|
}
|
|
}, {
|
|
key: 'connectedCallback',
|
|
value: function connectedCallback() {
|
|
var _this2 = this;
|
|
|
|
contentReady(this, function () {
|
|
if (_this2.hasAttribute('tabbar-id')) {
|
|
var page = util.findParent(_this2, 'ons-page');
|
|
_this2._tabbar = page && page.querySelector('#' + _this2.getAttribute('tabbar-id'));
|
|
if (!_this2._tabbar || _this2._tabbar.tagName !== 'ONS-TABBAR') {
|
|
util.throw('No tabbar with id ' + _this2.getAttribute('tabbar-id') + ' was found.');
|
|
}
|
|
|
|
_this2._tabbar.setAttribute('hide-tabs', '');
|
|
_setImmediate(function () {
|
|
return _this2._setChecked(_this2._tabbar.getActiveTabIndex());
|
|
});
|
|
|
|
_this2._tabbar.addEventListener('prechange', _this2._onTabbarPreChange);
|
|
}
|
|
});
|
|
|
|
this.addEventListener('change', this._onChange);
|
|
}
|
|
}, {
|
|
key: 'disconnectedCallback',
|
|
value: function disconnectedCallback() {
|
|
var _this3 = this;
|
|
|
|
contentReady(this, function () {
|
|
if (_this3._tabbar) {
|
|
_this3._tabbar.removeEventListener('prechange', _this3._onTabbarPreChange);
|
|
_this3._tabbar = null;
|
|
}
|
|
});
|
|
this.removeEventListener('change', this._onChange);
|
|
}
|
|
}, {
|
|
key: '_setChecked',
|
|
value: function _setChecked(index) {
|
|
this.children[index].firstElementChild.checked = true;
|
|
}
|
|
|
|
/**
|
|
* @method setActiveButton
|
|
* @signature setActiveButton(index, [options])
|
|
* @param {Number} index
|
|
* [en]Button index.[/en]
|
|
* [ja][/ja]
|
|
* @param {Object} [options]
|
|
* [en]Parameter object, works only if there is a connected tabbar. Supports the same options as `ons-tabbar`'s `setActiveTab` method.[/en]
|
|
* [ja][/ja]
|
|
* @description
|
|
* [en]Make button with the specified index active. If there is a connected tabbar it shows the corresponding tab page. In this case animations and their options can be specified by the second parameter.[/en]
|
|
* [ja][/ja]
|
|
* @return {Promise}
|
|
* [en]Resolves to the selected index or to the new page element if there is a connected tabbar.[/en]
|
|
* [ja][/ja]
|
|
*/
|
|
|
|
}, {
|
|
key: 'setActiveButton',
|
|
value: function setActiveButton(index, options) {
|
|
if (this._tabbar) {
|
|
return this._tabbar.setActiveTab(index, options);
|
|
}
|
|
|
|
this._setChecked(index);
|
|
this._postChange(index);
|
|
return _Promise.resolve(index);
|
|
}
|
|
|
|
/**
|
|
* @method getActiveButtonIndex
|
|
* @signature getActiveButtonIndex()
|
|
* @return {Number}
|
|
* [en]The index of the currently active button.[/en]
|
|
* [ja][/ja]
|
|
* @description
|
|
* [en]Returns button index of current active button. If active button is not found, returns -1.[/en]
|
|
* [ja][/ja]
|
|
*/
|
|
|
|
}, {
|
|
key: 'getActiveButtonIndex',
|
|
value: function getActiveButtonIndex() {
|
|
for (var i = this.children.length - 1; i >= 0; i--) {
|
|
// Array.findIndex
|
|
if (this.children[i].firstElementChild.checked) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
}, {
|
|
key: '_onChange',
|
|
value: function _onChange(event) {
|
|
event.stopPropagation();
|
|
this._tabbar ? this._tabbar.setActiveTab(this.getActiveButtonIndex(), { reject: false }) : this._postChange(this.getActiveButtonIndex());
|
|
}
|
|
}, {
|
|
key: '_onTabbarPreChange',
|
|
value: function _onTabbarPreChange(event) {
|
|
var _this4 = this;
|
|
|
|
_setImmediate(function () {
|
|
if (!event.detail.canceled) {
|
|
_this4._setChecked(event.index);
|
|
_this4._postChange(event.index);
|
|
}
|
|
});
|
|
}
|
|
}, {
|
|
key: '_postChange',
|
|
value: function _postChange(index) {
|
|
util.triggerElementEvent(this, 'postchange', {
|
|
index: index,
|
|
activeIndex: index,
|
|
lastActiveIndex: this._lastActiveIndex,
|
|
segmentItem: this.children[index]
|
|
});
|
|
this._lastActiveIndex = index;
|
|
}
|
|
|
|
/**
|
|
* @property disabled
|
|
* @type {Boolean}
|
|
* @description
|
|
* [en]Whether the segment is disabled or not.[/en]
|
|
* [ja]無効化されている場合に`true`。[/ja]
|
|
*/
|
|
|
|
}, {
|
|
key: 'attributeChangedCallback',
|
|
value: function attributeChangedCallback(name, last, current) {
|
|
switch (name) {
|
|
case 'class':
|
|
util.restoreClass(this, defaultClassName, scheme);
|
|
break;
|
|
case 'modifier':
|
|
ModifierUtil.onModifierChanged(last, current, this, scheme);
|
|
break;
|
|
}
|
|
}
|
|
}, {
|
|
key: 'disabled',
|
|
set: function set(value) {
|
|
return util.toggleAttribute(this, 'disabled', value);
|
|
},
|
|
get: function get() {
|
|
return this.hasAttribute('disabled');
|
|
}
|
|
}], [{
|
|
key: 'observedAttributes',
|
|
get: function get() {
|
|
return ['class', 'modifier'];
|
|
}
|
|
}, {
|
|
key: 'events',
|
|
get: function get() {
|
|
return ['postchange'];
|
|
}
|
|
}]);
|
|
|
|
return SegmentElement;
|
|
}(BaseElement);
|
|
|
|
export default SegmentElement;
|
|
|
|
|
|
onsElements.Segment = SegmentElement;
|
|
customElements.define('ons-segment', SegmentElement); |