Commit 01062789 authored by Nikolay Gromov's avatar Nikolay Gromov

add dropdown

parent 664bb481
☐ Добавить сексуальную стилизацию страницы библиотеки компонентов
☐ Сделать: таблицы — адаптивные таблицы — добавлять дата-атрибуты JS-ом
☐ Сделать: Кнопки: группа, в т.ч. с выпадающими элементами
☐ Сделать: Флажки и радиокнопки, выглядящеи как обычные кнопки
☐ Сделать: Кнопки: группа, в т.ч. с выпадающими элементами
☐ Сделать: Кнопка с иконкой
☐ Сделать: Кнопка-иконка
☐ Сделать: Текстовые поля: группа (в т.ч. с кнопками)
......@@ -19,7 +19,6 @@
☐ Сделать: Адаптивные вставки медиа-контента (http://foundation.zurb.com/sites/docs/flex-video.html)
☐ Сделать: Range c показанным выбранным значением
☐ Сделать: Множественный range
☐ Сделать: Дропдаун из любого элемента в любую сторону
☐ Сделать: Табы (вкладки) с реакцией на хеш
☐ Сделать: Off-canvas с тачем, правый и левый
☐ Сделать: Аккордеон
......@@ -42,3 +41,4 @@
✔ Вынести SVG-спрайты в отдельный компонент @done (05.03.2016 00:19)
✔ Сделать: Флажок-свитчер, радиокнопку-свитчер @done (16-03-05 12:44)
✔ Сделать: Селект с идентичными везде уголками и одинаковой высотой на win и osx @done (05.03.2016 20:18)
✔ Сделать: Дропдаун из любого элемента в любую сторону @done (07.03.2016 03:15)
......@@ -2,6 +2,6 @@
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/jquery.2.2.0.min.js"><\/script>')</script>
-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/jquery.js"><\/script>')</script>
<script src="js/script.min.js"></script>
<!--DEV
<span role="presentation" class="dropdown" id="test">
<a id="test_link" href="#" class="dropdown__toggler" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Ссылка</a>
<ul class="dropdown__menu" aria-labelledby="qwer">
<li><a href="#">Пункт списка (выпадает <code>ul</code>)</a></li>
<li class="dropdown__menu-separator"><a href="#">Пункт списка, после которого следует разделитель</a></li>
<li><a href="#">Пункт меню весьма длинный, такой, что прямо адски длинный, очень много, реально много слов!</a></li>
</ul>
</span>
<span role="presentation" class="dropdown" id="test_2">
<button class="dropdown__toggler btn" id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Выпадает список
</button>
<ul class="dropdown__menu" aria-labelledby="dLabel" id="qwer">
<li><a href="#">Пункт списка (выпадает <code>ul</code>)</a></li>
<li><a href="">Пункт меню весьма длинный</a></li>
<li><a href="">Второй пункт</a></li>
</ul>
</span>
<span role="presentation" class="dropdown" id="test_2">
<button class="dropdown__toggler btn" id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Выпадает блок
</button>
<div class="dropdown__menu">
Выпадает <code>div</code> с произвольным контентом. <a href="">Ссылка какая-то</a>.
<hr>
<form action="">
<input type="text">
<select name="" id="">
<option value="">Название пункта</option>
</select>
<textarea name="" id="" rows="3"></textarea>
<button class="btn">Отправить эту форму</button>
</form>
</div>
</span>
<span role="presentation" class="dropdown" id="test_2">
<button class="dropdown__toggler btn" id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Выпадение вверх от пр. края
</button>
<ul class="dropdown__menu dropdown__menu--up dropdown__menu--right" aria-labelledby="dLabel" id="qwer">
<li><a href="#">Пункт списка (выпадает <code>ul</code>)</a></li>
<li><a href="">Пункт меню весьма длинный</a></li>
<li><a href="">Второй пункт</a></li>
</ul>
</span>
-->
/* ========================================================================
* Основано на: Bootstrap dropdown.js v3.3.6, изменения минимальны
* ======================================================================== */
+function ($) {
'use strict';
// DROPDOWN CLASS DEFINITION
// =========================
var backdrop = '.dropdown-backdrop'
var toggle = '[data-toggle="dropdown"]'
var Dropdown = function (element) {
// $(element).on('click.bs.dropdown', this.toggle)
$(element).on('click.nth.dropdown', this.toggle)
}
Dropdown.VERSION = '3.3.6'
function getParent($this) {
var selector = $this.attr('data-target')
if (!selector) {
selector = $this.attr('href')
// selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
}
var $parent = selector && $(selector)
return $parent && $parent.length ? $parent : $this.parent()
}
function clearMenus(e) {
console.log('e: ' + e);
if (e && e.which === 3) return
$(backdrop).remove()
$(toggle).each(function () {
var $this = $(this)
var $parent = getParent($this)
var relatedTarget = { relatedTarget: this }
// if (!$parent.hasClass('open')) return
if (!$parent.hasClass('dropdown--open')) return
if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
// $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
// $parent.trigger(e = $.Event('hide.nth.dropdown', relatedTarget))
// if (e.isDefaultPrevented()) return
$this.attr('aria-expanded', 'false')
// $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
$parent.removeClass('dropdown--open').trigger($.Event('hidden.nth.dropdown', relatedTarget))
})
}
Dropdown.prototype.toggle = function (e) {
var $this = $(this)
// if ($this.is('.disabled, :disabled')) return
if ($this.is(':disabled')) return
var $parent = getParent($this)
// var isActive = $parent.hasClass('open')
var isActive = $parent.hasClass('dropdown--open')
// console.log($this);
clearMenus()
if (!isActive) {
// if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
if ('ontouchstart' in document.documentElement) {
// if mobile we use a backdrop because click events don't delegate
$(document.createElement('div'))
.addClass('dropdown-backdrop')
.insertAfter($(this))
.on('click', clearMenus)
}
var relatedTarget = { relatedTarget: this }
// $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
// $parent.trigger(e = $.Event('show.nth.dropdown', relatedTarget))
// if (e.isDefaultPrevented()) return
$this
.trigger('focus')
.attr('aria-expanded', 'true')
$parent
// .toggleClass('open')
.toggleClass('dropdown--open')
// .trigger($.Event('shown.bs.dropdown', relatedTarget))
.trigger($.Event('shown.nth.dropdown', relatedTarget))
}
return false
}
Dropdown.prototype.keydown = function (e) {
if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
console.log(e.which);
var $this = $(this)
e.preventDefault()
e.stopPropagation()
// if ($this.is('.disabled, :disabled')) return
if ($this.is(':disabled')) return
var $parent = getParent($this)
// var isActive = $parent.hasClass('open')
var isActive = $parent.hasClass('dropdown--open')
if (!isActive && e.which != 27 || isActive && e.which == 27) {
if (e.which == 27) $parent.find(toggle).trigger('focus')
return $this.trigger('click')
}
// var desc = ' li:not(.disabled):visible a'
// var $items = $parent.find('.dropdown-menu' + desc)
var $items = $parent.find('.dropdown__menu a')
if (!$items.length) return
var index = $items.index(e.target)
if (e.which == 38 && index > 0) index-- // up
if (e.which == 40 && index < $items.length - 1) index++ // down
if (!~index) index = 0
$items.eq(index).trigger('focus')
console.log($items.eq(index));
}
// DROPDOWN PLUGIN DEFINITION
// ==========================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
// var data = $this.data('bs.dropdown')
var data = $this.data('nth.dropdown')
// if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
if (!data) $this.data('nth.dropdown', (data = new Dropdown(this)))
if (typeof option == 'string') data[option].call($this)
})
}
var old = $.fn.dropdown
$.fn.dropdown = Plugin
$.fn.dropdown.Constructor = Dropdown
// DROPDOWN NO CONFLICT
// ====================
$.fn.dropdown.noConflict = function () {
$.fn.dropdown = old
return this
}
// APPLY TO STANDARD DROPDOWN ELEMENTS
// ===================================
$(document)
// .on('click.bs.dropdown.data-api', clearMenus)
// .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
// .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
// .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
// .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
.on('click.nth.dropdown.data-api', clearMenus)
.on('click.nth.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
.on('click.nth.dropdown.data-api', toggle, Dropdown.prototype.toggle)
.on('keydown.nth.dropdown.data-api', toggle, Dropdown.prototype.keydown)
.on('keydown.nth.dropdown.data-api', '.dropdown__menu', Dropdown.prototype.keydown)
}(jQuery);
@import "../../less/variables.less"; // только для удобства обращения к переменным
@import "../../less/mixins/mixins.less"; // только для удобства обращения к примесям
.dropdown {
position: relative;
display: inline-block;
&--open & {
&__menu {
z-index: @z-index-dropdown;
visibility: visible;
opacity: 1;
}
}
&__toggler {}
&__menu {
position: absolute;
top: 100%;
left: 0;
z-index: -1;
background-color: #fff;
color: @text-color;
padding: 1em;
margin: 0;
border: 1px solid @border-color;
border-radius: @border-radius;
opacity: 0;
visibility: hidden;
transition: opacity @transition-time;
&--up {
top: auto;
bottom: 100%;
}
&--right {
left: auto;
right: 0;
}
div& {
min-width: 26rem;
}
ul& {
min-width: 16rem;
// max-width: 30rem;
list-style: none;
padding: .3em 0;
> li > a {
display: block;
white-space: nowrap;
// width: 100%;
// overflow: hidden;
// text-overflow: ellipsis;
padding: .3em 1em;
color: @text-color;
text-decoration: none;
&:hover, &:focus {
background-color: @gray-lighter;
}
}
}
}
&__menu-separator {
&:not(:last-child) {
padding-bottom: .3em;
margin-bottom: .3em;
border-bottom: 1px solid @border-color;
}
}
}
......@@ -75,6 +75,7 @@
<dd>Некое, возможно, относительно длинное определение упомянутой сущности.</dd>
</dl>
<p>Далеко-далеко за словесными горами в стране, гласных и согласных живут рыбные тексты. Грустный предупредила, дал приставка составитель решила подпоясал запятых сих ручеек которой власти до, над жизни возвращайся силуэт что не курсивных.</p>
<div class="p">Это <code>div</code> с классом <code>.p</code>. Далеко-далеко за словесными горами в стране, гласных и согласных живут рыбные тексты. Грустный предупредила, дал приставка составитель решила подпоясал запятых сих ручеек которой власти до, над жизни возвращайся силуэт что не курсивных.</div>
</div>
<div class="col-md-6">
<p>
......@@ -625,6 +626,122 @@
<p>
<button class="btn btn--block">Button (block)</button>
</p>
</section>
<section class="blocks-library__item">
<h2 id="dropdown">Выпадающие элементы</h2>
<p>Свойства:</p>
<ul>
<li>Требуют jQuery.</li>
<li>Управление с клавиатуры.</li>
<li>Выпадать может <code>ul</code> или <code>div</code> с произвольным содержимым.</li>
<li>Cобытия с пространством имён.</li>
</ul>
<div class="p">
<span role="presentation" class="dropdown" id="test">
<a id="test_link" href="#" class="dropdown__toggler" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Ссылка</a>
<ul class="dropdown__menu" aria-labelledby="qwer">
<li><a href="#">Пункт списка (выпадает <code>ul</code>)</a></li>
<li class="dropdown__menu-separator"><a href="#">Пункт списка, после которого следует разделитель</a></li>
<li><a href="#">Пункт меню весьма длинный, такой, что прямо адски длинный, очень много, реально много слов!</a></li>
</ul>
</span>
<span role="presentation" class="dropdown" id="test_2">
<button class="dropdown__toggler btn" id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Выпадает список
</button>
<ul class="dropdown__menu" aria-labelledby="dLabel" id="qwer">
<li><a href="#">Пункт списка (выпадает <code>ul</code>)</a></li>
<li><a href="">Пункт меню весьма длинный</a></li>
<li><a href="">Второй пункт</a></li>
</ul>
</span>
<span role="presentation" class="dropdown" id="test_2">
<button class="dropdown__toggler btn" id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Выпадает блок
</button>
<div class="dropdown__menu">
Выпадает <code>div</code> с произвольным контентом. <a href="">Ссылка какая-то</a>.
<hr>
<form action="">
<input type="text">
<select name="" id="">
<option value="">Название пункта</option>
</select>
<textarea name="" id="" rows="3"></textarea>
<button class="btn">Отправить эту форму</button>
</form>
</div>
</span>
<span role="presentation" class="dropdown" id="test_2">
<button class="dropdown__toggler btn" id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Выпадение вверх от пр. края
</button>
<ul class="dropdown__menu dropdown__menu--up dropdown__menu--right" aria-labelledby="dLabel" id="qwer">
<li><a href="#">Пункт списка (выпадает <code>ul</code>)</a></li>
<li><a href="">Пункт меню весьма длинный</a></li>
<li><a href="">Второй пункт</a></li>
</ul>
</span>
</div>
<h3>События</h3>
<div class="row">
<div class="col-md-6">
<pre>
&lt;span role=&quot;presentation&quot; class=&quot;dropdown&quot; id=&quot;test&quot;&gt;
&lt;a href=&quot;#&quot; class=&quot;dropdown__toggler&quot; data-toggle=&quot;dropdown&quot; role=&quot;button&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot;&gt;&#x421;&#x441;&#x44b;&#x43b;&#x43a;&#x430; &#x441; &#x432;&#x44b;&#x43f;&#x430;&#x434;&#x430;&#x44e;&#x449;&#x438;&#x43c; &#x44d;&#x43b;&#x435;&#x43c;&#x435;&#x43d;&#x442;&#x43e;&#x43c;&lt;/a&gt;
&lt;ul class=&quot;dropdown__menu&quot; aria-labelledby=&quot;qwer&quot;&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;&#x41f;&#x443;&#x43d;&#x43a;&#x442; &#x441;&#x43f;&#x438;&#x441;&#x43a;&#x430; (&#x432;&#x44b;&#x43f;&#x430;&#x434;&#x430;&#x435;&#x442; &lt;code&gt;ul&lt;/code&gt;)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Another action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Something else here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Separated link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/span&gt;</pre>
</div>
<div class="col-md-6">
<pre>
// Факт открытия
$('#test').on('shown.nth.dropdown', function () {
console.log('shown.nth.dropdown');
});
// Факт закрытия
$('#test').on('hidden.nth.dropdown', function () {
console.log('hidden.nth.dropdown');
});</pre>
</div>
</div>
<!-- <div class="dropdown">
<a href="#" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown trigger
</a>
<div class="dropdown__menu">
<a href="">1111</a>
<a href="">1111</a>
<hr>
<form action="">
<input type="text">
<select name="" id="">
<option value="">111</option>
</select>
<textarea name="" id="" cols="30" rows="10"></textarea>
<button>111</button>
</form>
</div>
</div> -->
<!-- <div class="dropdown">
<span class="btn dropdown__toggler">Кнопка 2</span>
<div class="dropdown__content">выпадающий блок 2</div>
</div> -->
</section>
......
......@@ -15,3 +15,11 @@ function closest(el, selector) {
}
return null;
}
// Свой код с jQuery
$( document ).ready(function() {
});
......@@ -136,6 +136,7 @@ h4, h5, h6 {
margin-bottom: (@line-height / 2);
}
.p,
p,
ul,
ol,
......@@ -244,12 +245,12 @@ samp {
code {
color: @text-color;
background-color: @gray-lighter;
padding: .1em .3em;
padding: .06em .3em;
border-radius: @border-radius;
}
kbd {
padding: .1em .3em;
padding: .06em .3em;
color: @text-color;
background-color: @gray-lighter;
border-radius: @border-radius;
......
......@@ -21,3 +21,4 @@
@import "./src/blocks/thumb/thumb.less";
@import "./src/blocks/sprite-svg--localstorage/sprite-svg--localstorage.less";
@import "./src/blocks/field-toggler/field-toggler.less";
@import "./src/blocks/dropdown/dropdown.less";
......@@ -72,6 +72,12 @@
// Z-index
@z-index-dropdown: 10;
// Формы, кнопки
@field-padding-top: 0.313em;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment