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%;