Skip to content

Commit

Permalink
Use style tag for sticky columns instead of modifiers, for performanc…
Browse files Browse the repository at this point in the history
…e, until emberjs/rfcs#883 lands
  • Loading branch information
NullVoxPopuli committed Dec 30, 2022
1 parent 754f0e1 commit e786cc6
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 17 deletions.
7 changes: 4 additions & 3 deletions docs/plugins/sticky-column/demo/demo-a.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<tr class="relative">
{{#each this.table.columns as |column|}}
<th
{{this.table.modifiers.columnHeader column}}
class="{{if (this.isSticky column) 'bg-basement' 'bg-ground-floor'}}"
style="{{this.styleStringFor column}}"
>
<span class="name">{{column.name}}</span><br>
</th>
Expand All @@ -18,8 +18,8 @@
<tr class="relative">
{{#each this.table.columns as |column|}}
<td
{{this.table.modifiers.columnHeader column}}
class="{{if (this.isSticky column) 'bg-basement' 'bg-ground-floor'}}"
style="{{this.styleStringFor column}}"
>
{{column.getValueForRow row}}
</td>
Expand All @@ -34,7 +34,7 @@
import Component from '@glimmer/component';

import { headlessTable } from 'ember-headless-table';
import { StickyColumns, isSticky } from 'ember-headless-table/plugins/sticky-columns';
import { StickyColumns, isSticky, styleStringFor } from 'ember-headless-table/plugins/sticky-columns';
import { ColumnResizing } from 'ember-headless-table/plugins/column-resizing';
import { ColumnVisibility } from 'ember-headless-table/plugins/column-visibility';

Expand Down Expand Up @@ -69,6 +69,7 @@ export default class extends Component {
* [property on this component] = [variable in scope]
*/
isSticky = isSticky;
styleStringFor = styleStringFor;
}
```

46 changes: 46 additions & 0 deletions ember-headless-table/src/plugins/sticky-columns/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { htmlSafe } from '@ember/template';

import { meta } from '../-private/base';
import { StickyColumns } from './plugin';

Expand All @@ -9,3 +11,47 @@ export const isSticky = <DataType = unknown>(column: Column<DataType>) =>
export const styleFor = <DataType = unknown>(
column: Column<DataType>
): Partial<CSSStyleDeclaration> => meta.forColumn(column, StickyColumns).style;

/**
* In this plugin, buth header and cells have the same styles,
* if applicable.
*
* Until this RFC https://github.com/emberjs/rfcs/pull/883
* is merged and implemented, we can't performantly
* use modifiers for apply styles.
*
* In the mean time, we'll need to append style strings, which is more work
* for consumers, but is a reasonable trade-off for now.
*/
export const styleStringFor = <DataType = unknown>(
column: Column<DataType>
): ReturnType<typeof htmlSafe> => {
let columnMeta = meta.forColumn(column, StickyColumns);

let result = '';

if (columnMeta.isSticky) {
for (let [key, value] of Object.entries(columnMeta.style)) {
result += `${toStyle(key)}:${value};`;
}

result = ';' + result;
}

return htmlSafe(result);
};

/**
* the JS API for styles is camel case,
* but CSS is kebab-case. To save on complexity and
* amount of code, we have a super small conversion function
* for only the properties relevant to the sticky plugin.
*/
const toStyle = (key: string): string => {
switch (key) {
case 'zIndex':
return 'z-index';
default:
return key;
}
};
47 changes: 33 additions & 14 deletions ember-headless-table/src/plugins/sticky-columns/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { applyStyles } from '../-private/utils';
import type { ColumnApi } from '[public-plugin-types]';
import type { Column } from '[public-types]';

const DEFAULT_Z_INDEX = '8';

interface ColumnOptions {
/**
* Whether or not to enable stickiness on the column
Expand Down Expand Up @@ -44,27 +46,44 @@ export class StickyColumns extends BasePlugin<Signature> {
column: ColumnMeta,
};

conditionallyRemoveStyles = (element: HTMLElement) => {
if (element.style.getPropertyValue('position') === 'sticky') {
element.style.removeProperty('position');
}

if (element.style.getPropertyValue('left')) {
element.style.left = '';
}

if (element.style.getPropertyValue('right')) {
element.style.right = '';
}

if (element.style.zIndex === DEFAULT_Z_INDEX) {
element.style.zIndex = '';
}
};

headerCellModifier = (element: HTMLElement, { column }: ColumnApi) => {
let columnMeta = meta.forColumn(column, StickyColumns);

if (columnMeta.isSticky) {
applyStyles(element, columnMeta.style);
} else {
if (element.style.getPropertyValue('position') === 'sticky') {
element.style.removeProperty('position');
}

if (element.style.getPropertyValue('left')) {
element.style.left = '';
}
this.conditionallyRemoveStyles(element);
}
};

if (element.style.getPropertyValue('right')) {
element.style.right = '';
}
/**
* Not yet supported. Pending Ember RFC #883
*/
cellModifier = (element: HTMLElement, { column }: ColumnApi) => {
let columnMeta = meta.forColumn(column, StickyColumns);

if (element.style.zIndex === '8') {
element.style.zIndex = '';
}
if (columnMeta.isSticky) {
applyStyles(element, columnMeta.style);
} else {
this.conditionallyRemoveStyles(element);
}
};
}
Expand Down Expand Up @@ -136,7 +155,7 @@ export class ColumnMeta {
return {
position: 'sticky',
[this.position]: this.offset,
zIndex: '8',
zIndex: DEFAULT_Z_INDEX,
};
}

Expand Down

0 comments on commit e786cc6

Please sign in to comment.