Prevent action groups from being cutoff by the footer
1. Calculate where group is going to be, if it will get cut off, then dropup instead of down 2. As the action group can now drop up, the z-index should be higher than the previous rows, so add a top z-index higher than the others and use that when opened
This commit is contained in:
parent
9c43498354
commit
c1742a89dd
|
@ -1,21 +1,40 @@
|
|||
import Component from 'ember-collection/components/ember-collection';
|
||||
import needsRevalidate from 'ember-collection/utils/needs-revalidate';
|
||||
import identity from 'ember-collection/utils/identity';
|
||||
import Grid from 'ember-collection/layouts/grid';
|
||||
import SlotsMixin from 'ember-block-slots';
|
||||
import style from 'ember-computed-style';
|
||||
|
||||
import { computed, get, set } from '@ember/object';
|
||||
|
||||
const $$ = document.querySelectorAll.bind(document);
|
||||
const $$ = function(sel, context = document) {
|
||||
return context.querySelectorAll(sel);
|
||||
};
|
||||
const createSizeEvent = function(detail) {
|
||||
return {
|
||||
detail: { width: window.innerWidth, height: window.innerHeight },
|
||||
};
|
||||
};
|
||||
// need to copy this in wholesale as there is no way to import it
|
||||
// TODO: separate both Cell and ZIndexedGrid out
|
||||
class Cell {
|
||||
constructor(key, item, index, style) {
|
||||
this.key = key;
|
||||
this.hidden = false;
|
||||
this.item = item;
|
||||
this.index = index;
|
||||
this.style = style;
|
||||
}
|
||||
}
|
||||
const maxZIndex = 10000;
|
||||
class ZIndexedGrid extends Grid {
|
||||
formatItemStyle(index, w, h) {
|
||||
let style = super.formatItemStyle(...arguments);
|
||||
style += 'z-index: ' + (10000 - index);
|
||||
formatItemStyle(index, w, h, checked) {
|
||||
let style = super.formatItemStyle(index, w, h);
|
||||
let zIndex = maxZIndex - index;
|
||||
if (checked == index) {
|
||||
zIndex = maxZIndex + 1;
|
||||
}
|
||||
style += 'z-index: ' + zIndex;
|
||||
return style;
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +56,21 @@ const change = function(e) {
|
|||
const value = e.currentTarget.value;
|
||||
if (value != get(this, 'checked')) {
|
||||
set(this, 'checked', value);
|
||||
if (e.currentTarget.getAttribute('id') !== 'actions_close') {
|
||||
const $tr = closest('tr', e.currentTarget);
|
||||
const $group = [...$('~ ul', e.currentTarget)][0];
|
||||
const $footer = [...$$('footer[role="contentinfo"]')][0];
|
||||
const groupRect = $group.getBoundingClientRect();
|
||||
const footerRect = $footer.getBoundingClientRect();
|
||||
const groupBottom = groupRect.top + $group.clientHeight;
|
||||
const footerTop = footerRect.top;
|
||||
if (groupBottom > footerTop) {
|
||||
$group.classList.add('above');
|
||||
} else {
|
||||
$group.classList.remove('above');
|
||||
}
|
||||
$tr.style.zIndex = maxZIndex + 1;
|
||||
}
|
||||
} else {
|
||||
set(this, 'checked', null);
|
||||
}
|
||||
|
@ -109,6 +143,108 @@ export default Component.extend(SlotsMixin, {
|
|||
needsRevalidate(this);
|
||||
}
|
||||
},
|
||||
// need to overwrite this completely so I can pass through the checked index
|
||||
// for `formatItemStyle` in 3 places
|
||||
updateCells: function() {
|
||||
if (!this._items) {
|
||||
return;
|
||||
}
|
||||
const numItems = get(this._items, 'length');
|
||||
if (this._cellLayout.length !== numItems) {
|
||||
this._cellLayout.length = numItems;
|
||||
}
|
||||
|
||||
var priorMap = this._cellMap;
|
||||
var cellMap = Object.create(null);
|
||||
|
||||
var index = this._cellLayout.indexAt(
|
||||
this._scrollLeft,
|
||||
this._scrollTop,
|
||||
this._clientWidth,
|
||||
this._clientHeight
|
||||
);
|
||||
var count = this._cellLayout.count(
|
||||
this._scrollLeft,
|
||||
this._scrollTop,
|
||||
this._clientWidth,
|
||||
this._clientHeight
|
||||
);
|
||||
var items = this._items;
|
||||
var bufferBefore = Math.min(index, this._buffer);
|
||||
index -= bufferBefore;
|
||||
count += bufferBefore;
|
||||
count = Math.min(count + this._buffer, get(items, 'length') - index);
|
||||
var i, style, itemIndex, itemKey, cell;
|
||||
|
||||
var newItems = [];
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
itemIndex = index + i;
|
||||
itemKey = identity(items.objectAt(itemIndex));
|
||||
if (priorMap) {
|
||||
cell = priorMap[itemKey];
|
||||
}
|
||||
if (cell) {
|
||||
// additional `checked` argument
|
||||
style = this._cellLayout.formatItemStyle(
|
||||
itemIndex,
|
||||
this._clientWidth,
|
||||
this._clientHeight,
|
||||
this.checked
|
||||
);
|
||||
set(cell, 'style', style);
|
||||
set(cell, 'hidden', false);
|
||||
set(cell, 'key', itemKey);
|
||||
cellMap[itemKey] = cell;
|
||||
} else {
|
||||
newItems.push(itemIndex);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < this._cells.length; i++) {
|
||||
cell = this._cells[i];
|
||||
if (!cellMap[cell.key]) {
|
||||
if (newItems.length) {
|
||||
itemIndex = newItems.pop();
|
||||
let item = items.objectAt(itemIndex);
|
||||
itemKey = identity(item);
|
||||
// additional `checked` argument
|
||||
style = this._cellLayout.formatItemStyle(
|
||||
itemIndex,
|
||||
this._clientWidth,
|
||||
this._clientHeight,
|
||||
this.checked
|
||||
);
|
||||
set(cell, 'style', style);
|
||||
set(cell, 'key', itemKey);
|
||||
set(cell, 'index', itemIndex);
|
||||
set(cell, 'item', item);
|
||||
set(cell, 'hidden', false);
|
||||
cellMap[itemKey] = cell;
|
||||
} else {
|
||||
set(cell, 'hidden', true);
|
||||
set(cell, 'style', 'height: 0; display: none;');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < newItems.length; i++) {
|
||||
itemIndex = newItems[i];
|
||||
let item = items.objectAt(itemIndex);
|
||||
itemKey = identity(item);
|
||||
// additional `checked` argument
|
||||
style = this._cellLayout.formatItemStyle(
|
||||
itemIndex,
|
||||
this._clientWidth,
|
||||
this._clientHeight,
|
||||
this.checked
|
||||
);
|
||||
cell = new Cell(itemKey, item, itemIndex, style);
|
||||
cellMap[itemKey] = cell;
|
||||
this._cells.pushObject(cell);
|
||||
}
|
||||
this._cellMap = cellMap;
|
||||
},
|
||||
actions: {
|
||||
click: function(e) {
|
||||
const name = e.target.nodeName.toLowerCase();
|
||||
|
|
|
@ -70,19 +70,30 @@
|
|||
%action-group ul {
|
||||
position: absolute;
|
||||
right: -10px;
|
||||
top: 35px;
|
||||
padding: 1px;
|
||||
}
|
||||
%action-group ul::before {
|
||||
position: absolute;
|
||||
right: 18px;
|
||||
top: -6px;
|
||||
content: '';
|
||||
display: block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
%action-group ul:not(.above) {
|
||||
top: 35px;
|
||||
}
|
||||
%action-group ul:not(.above)::before {
|
||||
top: -6px;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
%action-group ul.above {
|
||||
bottom: 35px;
|
||||
}
|
||||
%action-group ul.above::before {
|
||||
bottom: -6px;
|
||||
transform: rotate(225deg);
|
||||
}
|
||||
%action-group li {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
|
Loading…
Reference in New Issue