From 206cb0bbb565a75f4505e3715afb29f66c04ae93 Mon Sep 17 00:00:00 2001 From: Christopher Garrett <opensource@pzuraq.com> Date: Fri, 1 Jun 2018 11:17:39 -0700 Subject: [PATCH] [styles] Fixes up the markup for integration with style framework --- addon/-private/collapse-tree.js | 13 +++- addon/-private/column-tree.js | 8 +-- addon/-private/utils/reorder-indicators.js | 40 ++++++------- addon/components/ember-td/component.js | 6 ++ addon/components/ember-td/template.hbs | 59 ++++++++++++------- .../ember-th/action-dropdown/component.js | 24 ++++++++ addon/components/ember-th/component.js | 8 ++- addon/components/ember-th/template.hbs | 4 +- addon/components/ember-thead/component.js | 3 +- addon/components/ember-tr/component.js | 4 ++ addon/styles/addon.scss | 26 ++++++++ app/styles/ember-table/default.scss | 27 +-------- package.json | 2 +- .../pods/scenarios/performance/controller.js | 6 +- .../pods/scenarios/performance/template.hbs | 22 +++++-- .../app/pods/scenarios/simple/template.hbs | 1 - tests/dummy/app/styles/app.scss | 4 +- tests/dummy/app/styles/tables.scss | 2 - 18 files changed, 173 insertions(+), 86 deletions(-) create mode 100644 addon/components/ember-th/action-dropdown/component.js diff --git a/addon/-private/collapse-tree.js b/addon/-private/collapse-tree.js index 39bc380a7..4df1b416a 100644 --- a/addon/-private/collapse-tree.js +++ b/addon/-private/collapse-tree.js @@ -46,6 +46,17 @@ class TableRowMeta extends EmberObject { @readOnly('_tree.selectMode') selectMode; + @computed('selectMode') + get canSelect() { + let selectMode = this.get('selectMode'); + + return ( + selectMode === SELECT_MODE.MULTIPLE || + selectMode === SELECT_MODE.GROUPING || + selectMode === SELECT_MODE.SINGLE + ); + } + @computed('selectMode') get canMultiSelect() { let selectMode = this.get('selectMode'); @@ -81,7 +92,7 @@ class TableRowMeta extends EmberObject { return isArray(children) && get(children, 'length') > 0; } - @computed('_parentMeta') + @computed('_parentMeta.depth') get depth() { let parentMeta = get(this, '_parentMeta'); diff --git a/addon/-private/column-tree.js b/addon/-private/column-tree.js index e1cf67b85..decb45df0 100644 --- a/addon/-private/column-tree.js +++ b/addon/-private/column-tree.js @@ -714,7 +714,7 @@ export default class ColumnTree extends EmberObject { this._reorderMainIndicator = new MainIndicator(this.container, node.element, bounds); this._reorderDropIndicator = new DropIndicator(this.container, node.element, bounds); - this.container.classList.add('et-unselectable'); + this.container.classList.add('is-reordering'); } updateReorder(node, clientX) { @@ -762,7 +762,7 @@ export default class ColumnTree extends EmberObject { this._nextUpdateScroll = null; } - this.container.classList.remove('et-unselectable'); + this.container.classList.remove('is-reordering'); this.sendAction('onReorder', get(node, 'column'), get(closestColumn, 'column')); } @@ -770,7 +770,7 @@ export default class ColumnTree extends EmberObject { startResize(node, clientX) { this.clientX = clientX; - this.container.classList.add('et-unselectable'); + this.container.classList.add('is-resizing'); } updateResize(node, clientX) { @@ -836,7 +836,7 @@ export default class ColumnTree extends EmberObject { this._nextUpdateScroll = null; } - this.container.classList.remove('et-unselectable'); + this.container.classList.remove('is-resizing'); this.sendAction('onResize', get(node, 'column')); } diff --git a/addon/-private/utils/reorder-indicators.js b/addon/-private/utils/reorder-indicators.js index f6e8ebb6f..c472176a2 100644 --- a/addon/-private/utils/reorder-indicators.js +++ b/addon/-private/utils/reorder-indicators.js @@ -1,7 +1,5 @@ import { getScale, getOuterClientRect, getInnerClientRect } from './element'; -const DROP_INDICATOR_WIDTH = 5; - function createElement(mainClass, dimensions) { let element = document.createElement('div'); @@ -15,32 +13,31 @@ function createElement(mainClass, dimensions) { } class ReorderIndicator { - constructor(container, element, bounds, mainClass, width) { + constructor(container, element, bounds, mainClass, child) { this.container = container; this.element = element; this.bounds = bounds; - this.width = width; + this.child = child; this.scale = getScale(container); let scrollTop = this.container.scrollTop; let scrollLeft = this.container.scrollLeft; - let { height: containerHeight, top: containerTop, left: containerLeft } = getInnerClientRect( - this.container - ); + let { top: containerTop, left: containerLeft } = getInnerClientRect(this.container); - let { top: elementTop, left: elementLeft } = getOuterClientRect(this.element); + let { top: elementTop, left: elementLeft, width: elementWidth } = getOuterClientRect( + this.element + ); let top = (elementTop - containerTop) * this.scale + scrollTop; let left = (elementLeft - containerLeft) * this.scale + scrollLeft; - let height = (containerHeight - (containerTop - elementTop)) * this.scale; + let width = elementWidth * this.scale; - this.indicatorElement = createElement(mainClass, { - width, - height, - top, - left, - }); + this.indicatorElement = createElement(mainClass, { top, left, width }); + + if (child) { + this.indicatorElement.appendChild(child); + } this.container.appendChild(this.indicatorElement); this._left = left; @@ -57,10 +54,12 @@ class ReorderIndicator { set left(newLeft) { let { leftBound, rightBound } = this.bounds; + let width = this.indicatorElement.offsetWidth; + if (newLeft < leftBound) { newLeft = leftBound; - } else if (newLeft + this.width > rightBound) { - newLeft = rightBound - this.width; + } else if (newLeft + width > rightBound) { + newLeft = rightBound - width; } this.indicatorElement.style.left = `${newLeft}px`; @@ -70,14 +69,15 @@ class ReorderIndicator { export class MainIndicator extends ReorderIndicator { constructor(container, element, bounds) { - let width = getOuterClientRect(element).width * getScale(element); + // let width = getOuterClientRect(element).width * getScale(element); + let child = element.cloneNode(true); - super(container, element, bounds, 'et-reorder-main-indicator', width); + super(container, element, bounds, 'et-reorder-main-indicator', child); } } export class DropIndicator extends ReorderIndicator { constructor(container, element, bounds) { - super(container, element, bounds, 'et-reorder-drop-indicator', DROP_INDICATOR_WIDTH); + super(container, element, bounds, 'et-reorder-drop-indicator'); } } diff --git a/addon/components/ember-td/component.js b/addon/components/ember-td/component.js index a01b11abb..2b32153af 100644 --- a/addon/components/ember-td/component.js +++ b/addon/components/ember-td/component.js @@ -32,6 +32,7 @@ export default class EmberTd extends Component { @readOnly('unwrappedApi.rowValue') rowValue; @readOnly('unwrappedApi.rowMeta') rowMeta; + @className @equal('columnMeta.index', 0) isFirstColumn; @@ -54,6 +55,11 @@ export default class EmberTd extends Component { @equal('columnMeta.isFixed', 'right') isFixedRight; + @computed('rowMeta.depth') + get depthClass() { + return `depth-${this.get('rowMeta.depth')}`; + } + @attribute @computed('columnMeta.{width,offsetLeft,offsetRight}', 'isFixed') get style() { diff --git a/addon/components/ember-td/template.hbs b/addon/components/ember-td/template.hbs index 550ee4887..f5c760c45 100644 --- a/addon/components/ember-td/template.hbs +++ b/addon/components/ember-td/template.hbs @@ -1,25 +1,44 @@ {{#if isFirstColumn}} - {{#if canMultiSelect}} - {{-ember-table-private/simple-checkbox - data-test-select-row=true - checked=rowMeta.isSelected - onChange="onSelectionToggled" - ariaLabel="Select row" - }} - {{/if}} + <div class="et-cell-container"> + {{#if canMultiSelect}} + <span class="et-toggle-select"> + {{-ember-table-private/simple-checkbox + data-test-select-row=true + checked=rowMeta.isSelected + onChange="onSelectionToggled" + ariaLabel="Select row" + }} + <span></span> + </span> + {{/if}} - {{#if canCollapse}} - {{-ember-table-private/simple-checkbox - data-test-collapse-row=true - checked=rowMeta.isCollapsed - onChange="onCollapseToggled" - ariaLabel="Collapse row" - }} - {{/if}} -{{/if}} + {{#if canCollapse}} + <span class="et-toggle-collapse et-depth-indent {{depthClass}}"> + {{-ember-table-private/simple-checkbox + data-test-collapse-row=true + checked=rowMeta.isCollapsed + onChange="onCollapseToggled" + ariaLabel="Collapse row" + }} + <span></span> + </span> + {{else}} + <div class="et-depth-indent et-depth-placeholder {{depthClass}}"></div> + {{/if}} -{{#if hasBlock}} - {{yield cellValue columnValue rowValue cellMeta columnMeta rowMeta}} + <div class="et-cell-content"> + {{#if hasBlock}} + {{yield cellValue columnValue rowValue cellMeta columnMeta rowMeta}} + {{else}} + {{cellValue}} + {{/if}} + </div> + </div> {{else}} - {{cellValue}} + {{#if hasBlock}} + {{yield cellValue columnValue rowValue cellMeta columnMeta rowMeta}} + {{else}} + {{cellValue}} + {{/if}} {{/if}} + diff --git a/addon/components/ember-th/action-dropdown/component.js b/addon/components/ember-th/action-dropdown/component.js new file mode 100644 index 000000000..98c8d9f19 --- /dev/null +++ b/addon/components/ember-th/action-dropdown/component.js @@ -0,0 +1,24 @@ +import Component from '@ember/component'; + +import { action } from '@ember-decorators/object'; +import { tagName, classNames } from '@ember-decorators/component'; +import { argument } from '@ember-decorators/argument'; + +import layout from './template'; + +@tagName('button') +@classNames('et-action-dropdown') +export default class EmberThDropdown extends Component { + layout = layout; + + @argument dropdownActions; + + @argument onDropdownAction; + + @action + sendDropdownAction(close, ...args) { + this.sendAction('onDropdownAction', ...args); + + close(); + } +} diff --git a/addon/components/ember-th/component.js b/addon/components/ember-th/component.js index 890038c61..d97675999 100644 --- a/addon/components/ember-th/component.js +++ b/addon/components/ember-th/component.js @@ -37,12 +37,16 @@ export default class EmberTh extends Component { /** Indicates if this column can be resized. */ - @readOnly('unwrappedApi.enableResize') resizeEnabled; + @className('is-resizable') + @readOnly('unwrappedApi.enableResize') + resizeEnabled; /** Indicates if this column can be reordered. */ - @readOnly('unwrappedApi.enableReorder') reorderEnabled; + @className('is-reorderable') + @readOnly('unwrappedApi.enableReorder') + reorderEnabled; /** Any sorts applied to the table. diff --git a/addon/components/ember-th/template.hbs b/addon/components/ember-th/template.hbs index 8b2a67803..a13b28b29 100644 --- a/addon/components/ember-th/template.hbs +++ b/addon/components/ember-th/template.hbs @@ -4,11 +4,11 @@ {{columnValue.name}} {{#if isSorted}} - <div data-test-sort-indicator class="et-sort-indicator {{if isSortedAsc 'is-ascending' 'is-descending'}}"> + <span data-test-sort-indicator class="et-sort-indicator {{if isSortedAsc 'is-ascending' 'is-descending'}}"> {{#if isMultiSorted}} {{sortIndex}} {{/if}} - </div> + </span> {{/if}} {{/if}} diff --git a/addon/components/ember-thead/component.js b/addon/components/ember-thead/component.js index f4e432606..e6211b1c2 100644 --- a/addon/components/ember-thead/component.js +++ b/addon/components/ember-thead/component.js @@ -11,6 +11,7 @@ import { computed } from '@ember-decorators/object'; import { notEmpty } from '@ember-decorators/object/computed'; import { tagName } from '@ember-decorators/component'; +import { closest } from '../../-private/utils/element'; import { sortMultiple, compareValues } from '../../-private/utils/sort'; import ColumnTree, { RESIZE_MODE, FILL_MODE, WIDTH_CONSTRAINT } from '../../-private/column-tree'; @@ -190,7 +191,7 @@ export default class EmberTHead extends Component { didInsertElement() { super.didInsertElement(...arguments); - this._container = this.element.closest('.ember-table'); + this._container = closest(this.element, '.ember-table'); this.columnTree.registerContainer(this._container); diff --git a/addon/components/ember-tr/component.js b/addon/components/ember-tr/component.js index 249b58134..ac90f189c 100644 --- a/addon/components/ember-tr/component.js +++ b/addon/components/ember-tr/component.js @@ -43,6 +43,10 @@ export default class EmberTableRow extends Component { @readOnly('rowMeta.isSelected') isSelected; + @className + @readOnly('rowMeta.canSelect') + isSelectable; + click(event) { let inputParent = closest(event.target, 'input, button, label, a, select'); diff --git a/addon/styles/addon.scss b/addon/styles/addon.scss index 746ebbc77..2e9120c4c 100644 --- a/addon/styles/addon.scss +++ b/addon/styles/addon.scss @@ -24,6 +24,22 @@ } } + th { + z-index: 2; + + &:not(.is-fixed-right) { + .et-header-resize-area { + right: 0; + } + } + + &.is-fixed-right { + .et-header-resize-area { + left: 0; + } + } + } + td.is-fixed-left, td.is-fixed-right { z-index: 3; @@ -69,6 +85,16 @@ display: none; } + .et-header-resize-area { + cursor: col-resize; + + width: 10px; + height: 100%; + + position: absolute; + top: 0; + } + @media speech { .et-sort-toggle { display: block; diff --git a/app/styles/ember-table/default.scss b/app/styles/ember-table/default.scss index fe5083ae8..ec3cda77c 100644 --- a/app/styles/ember-table/default.scss +++ b/app/styles/ember-table/default.scss @@ -12,6 +12,7 @@ $table-hover-color: #e5edf8; td { white-space: nowrap; text-overflow: ellipsis; + overflow: hidden; font-size: 20px; padding: 4px 10px; } @@ -65,17 +66,6 @@ $table-hover-color: #e5edf8; border-right: none; } - .et-header-resize-area { - cursor: col-resize; - width: 10px; - height: 100%; - position: absolute; - top: 0; - right: 0; - - user-select: none; - } - &.is-fixed-right { border-left: solid 1px $table-border-color; @@ -101,19 +91,4 @@ $table-hover-color: #e5edf8; background-color: #227ecb; } } - - .et-reorder-main-indicator { - position: absolute; - background: #cccccc; - opacity: 0.8; - cursor: move; - z-index: 10; - } - - .et-reorder-drop-indicator { - position: absolute; - background: #444444; - opacity: 0.6; - z-index: 10; - } } diff --git a/package.json b/package.json index 0270b153b..70bd7988c 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "@addepar/eslint-config": "^4.0.0", "@addepar/prettier-config": "^1.0.0", "@addepar/sass-lint-config": "^2.0.1", - "@addepar/style-toolbox": "^0.4.0", + "@addepar/style-toolbox": "^0.5.0", "@types/ember": "^2.8.22", "babel-eslint": "^8.2.3", "babel-plugin-transform-object-rest-spread": "^6.26.0", diff --git a/tests/dummy/app/pods/scenarios/performance/controller.js b/tests/dummy/app/pods/scenarios/performance/controller.js index d2f199e53..92ba4a2e4 100644 --- a/tests/dummy/app/pods/scenarios/performance/controller.js +++ b/tests/dummy/app/pods/scenarios/performance/controller.js @@ -6,7 +6,11 @@ import { generateRows, generateColumns } from '../../../utils/generators'; export default class BasicController extends Controller { @computed get rows() { - return generateRows(10, 3, (row, key) => `${row.id}${key}`); + let rows = generateRows(10, 3, (row, key) => `${row.id}${key}`); + + rows[0].children[0].children[0].children = generateRows(10, 1, (row, key) => `${row.id}${key}`); + + return rows; } @computed diff --git a/tests/dummy/app/pods/scenarios/performance/template.hbs b/tests/dummy/app/pods/scenarios/performance/template.hbs index 937dbfefb..07d5216be 100644 --- a/tests/dummy/app/pods/scenarios/performance/template.hbs +++ b/tests/dummy/app/pods/scenarios/performance/template.hbs @@ -1,20 +1,34 @@ <div class="demo-container fixed-width"> {{#ember-table as |t|}} - {{ember-thead + {{#ember-thead api=t columns=columns sorts=sorts - headerActions=headerActions onUpdateSorts="onUpdateSorts" - onHeaderAction="onHeaderAction" + + as |h| }} + {{#ember-tr api=h as |r|}} + {{ember-th api=r}} + {{/ember-tr}} + {{/ember-thead}} - {{ember-tbody + {{#ember-tbody api=t rows=rows selectedRows=selectedRows onSelect="onSelect" selectMode="grouping" + + as |b| }} + {{#ember-tr api=b as |r|}} + {{#ember-td api=r as |value column row cellMeta columnMeta|}} + {{value}} + + {{#if (eq columnMeta.index 0)}}lorem ipsum dolor{{/if}} + {{/ember-td}} + {{/ember-tr}} + {{/ember-tbody}} {{/ember-table}} </div> diff --git a/tests/dummy/app/pods/scenarios/simple/template.hbs b/tests/dummy/app/pods/scenarios/simple/template.hbs index 3b173c509..11dfed626 100644 --- a/tests/dummy/app/pods/scenarios/simple/template.hbs +++ b/tests/dummy/app/pods/scenarios/simple/template.hbs @@ -8,7 +8,6 @@ {{ember-tbody api=t rows=rows - onSelect=(action (mut selectedRows)) selectedRows=selectedRows }} {{/ember-table}} diff --git a/tests/dummy/app/styles/app.scss b/tests/dummy/app/styles/app.scss index 01adbbb2e..16cf534c5 100644 --- a/tests/dummy/app/styles/app.scss +++ b/tests/dummy/app/styles/app.scss @@ -1,5 +1,7 @@ @import './tables'; -@import '@addepar/style-toolbox/variables/index'; +@import '@addepar/style-toolbox/core-variables/index'; +@import '@addepar/style-toolbox/utilities/index'; +@import '@addepar/style-toolbox/elements/index'; @import '@addepar/style-toolbox/components/index'; $navy: #001f3f; diff --git a/tests/dummy/app/styles/tables.scss b/tests/dummy/app/styles/tables.scss index fdd7039a0..82a49505e 100644 --- a/tests/dummy/app/styles/tables.scss +++ b/tests/dummy/app/styles/tables.scss @@ -1,5 +1,3 @@ -@import '../styles/ember-table/default'; - .demo-container { position: relative; width: 100%;