@spectric/ui 0.0.13 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectric/ui",
3
- "version": "0.0.13",
3
+ "version": "0.0.14",
4
4
  "type": "module",
5
5
  "main": "./dist/index.es.js",
6
6
  "module": "./dist/index.es.js",
@@ -56,7 +56,7 @@ class DomListener implements IDisposable {
56
56
  export class DisposableElement extends LitElement {
57
57
  private readonly _disposables = new Set<IDisposable>();
58
58
  private _isDisposed = false;
59
- private _disposableListeners: { target: DisposableTarget, event: string, handler: any }[] = []
59
+ private _disposableListeners: { target: DisposableTarget, event: string, handler: any, options?: AddEventListenerOptions }[] = []
60
60
  private _connected: boolean = false;
61
61
  /**
62
62
  * Creates listeners on a target that will automatically get cleaned up when the element is removed from the DOM. This prevents memory leaks.
@@ -64,17 +64,17 @@ export class DisposableElement extends LitElement {
64
64
  * @param event The event name
65
65
  * @param handler The event handler
66
66
  */
67
- public addDisposableListener<K extends keyof GlobalEventHandlersEventMap>(target: DisposableTarget, event: K, handler: (event: GlobalEventHandlersEventMap[K]) => void): void
68
- public addDisposableListener<K extends keyof SpectricGlobalEvents>(target: DisposableTarget, event: K, handler: SpectricGlobalEvents[K]): void
69
- public addDisposableListener(target: DisposableTarget, event: string, handler: any): void {
67
+ public addDisposableListener<K extends keyof GlobalEventHandlersEventMap>(target: DisposableTarget, event: K, handler: (event: GlobalEventHandlersEventMap[K]) => void, options?: AddEventListenerOptions): void
68
+ public addDisposableListener<K extends keyof SpectricGlobalEvents>(target: DisposableTarget, event: K, handler: SpectricGlobalEvents[K], options?: AddEventListenerOptions): void
69
+ public addDisposableListener(target: DisposableTarget, event: string, handler: any, options?: AddEventListenerOptions): void {
70
70
  let exists = this._disposableListeners.find(d => d.event === event && d.target === target && d.handler === handler)
71
71
  if (exists) {
72
72
  console.warn("Event handler already exists best practice is to add the this in the constructor")
73
73
  return //Event handler has already been added, maybe they added it in a callback
74
74
  }
75
- this._disposableListeners.push({ target, event, handler })
75
+ this._disposableListeners.push({ target, event, handler, options })
76
76
  if (this._connected) {
77
- this.registerDisposable(new DomListener(target, event, handler))
77
+ this.registerDisposable(new DomListener(target, event, handler, options))
78
78
  }
79
79
  }
80
80
  public registerDisposable<T extends IDisposable>(o: T): T {
@@ -97,8 +97,8 @@ export class DisposableElement extends LitElement {
97
97
  super.connectedCallback();
98
98
  this._connected = true
99
99
  this._isDisposed = false
100
- this._disposableListeners.forEach(({ target, event, handler }) => {
101
- this.registerDisposable(new DomListener(target, event, handler))
100
+ this._disposableListeners.forEach(({ target, event, handler, options }) => {
101
+ this.registerDisposable(new DomListener(target, event, handler, options))
102
102
  })
103
103
  }
104
104
 
@@ -1,4 +1,4 @@
1
- import { CSSResultGroup, html, LitElement } from 'lit';
1
+ import { CSSResultGroup, html } from 'lit';
2
2
  import { styleMap } from 'lit/directives/style-map.js';
3
3
 
4
4
  import style from './button.css';
@@ -6,6 +6,7 @@ import { customElement, property } from 'lit/decorators.js';
6
6
  import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from './types';
7
7
  import { DomRenderable } from './table';
8
8
  import { TooltipPostionsTypes } from './tooltip';
9
+ import { DisposableElement } from '../classes/DisposibleElement';
9
10
 
10
11
  export enum ButtonSizes {
11
12
  large = "large",
@@ -45,7 +46,7 @@ const MODES = {
45
46
  }
46
47
 
47
48
  @customElement('spectric-button')
48
- export class SpectricButton extends LitElement implements ButtonProps {
49
+ export class SpectricButton extends DisposableElement implements ButtonProps {
49
50
 
50
51
  static styles?: CSSResultGroup | undefined = style;
51
52
  @property({ type: String, reflect: true })
@@ -66,14 +67,11 @@ export class SpectricButton extends LitElement implements ButtonProps {
66
67
  tooltip?: DomRenderable;
67
68
  @property({ type: String, reflect: true })
68
69
  tooltipPosition?: TooltipPostionsTypes = "right";
69
- connectedCallback(): void {
70
- super.connectedCallback()
71
- this.addEventListener("click", this._onClick, { capture: true })
72
- }
73
- disconnectedCallback(): void {
74
- super.disconnectedCallback()
75
- this.removeEventListener("click", this._onClick)
70
+ constructor() {
71
+ super()
72
+ this.addDisposableListener(this, "click", this._onClick, { capture: true })
76
73
  }
74
+
77
75
  private _onClick = (e: MouseEvent) => {
78
76
  if (e instanceof CustomEvent) {
79
77
  return
@@ -1,6 +1,6 @@
1
1
  import { html, LitElement, PropertyValues } from 'lit';
2
2
  import "../Button";
3
- import { customElement, property, } from 'lit/decorators.js';
3
+ import { customElement, property, query, } from 'lit/decorators.js';
4
4
  import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from '../types';
5
5
  export const PaginationElementTag = "spectric-pagination"
6
6
  import "./pagination.css"
@@ -37,6 +37,8 @@ export class PaginationElement extends LitElement implements PaginationProps {
37
37
  @property({ type: Array })
38
38
  pageSizeOptions = [10, 20, 50, 100, 1000];
39
39
 
40
+ @query("select")
41
+ select?: HTMLSelectElement
40
42
  /**
41
43
  * Size of the pagination buttons
42
44
  */
@@ -48,6 +50,15 @@ export class PaginationElement extends LitElement implements PaginationProps {
48
50
  protected updated(_changedProperties: PropertyValues): void {
49
51
  if (_changedProperties.has("pageSize") && !this.pageSizeOptions.includes(this.pageSize)) {
50
52
  this.pageSizeOptions = [...this.pageSizeOptions, this.pageSize].sort((a, b) => a - b)
53
+ /**
54
+ * If an option isn't present in the select options list it cannot update its value until after the option is present.
55
+ * We requests an animation frame to make sure we the value was set correctly after the option is added. We update it if the value is incorrect
56
+ */
57
+ requestAnimationFrame(() => {
58
+ if (this.select && this.select.value !== String(this.pageSize)) {
59
+ this.select.value = String(this.pageSize)
60
+ }
61
+ })
51
62
  }
52
63
  }
53
64
  private _handlePageUp = () => {
@@ -59,6 +70,8 @@ export class PaginationElement extends LitElement implements PaginationProps {
59
70
  this._emitChange()
60
71
  }
61
72
  private _handleSizeChange = (e: any) => {
73
+ e.stopPropagation()
74
+ e.preventDefault()
62
75
  let value = parseInt(e.target.value)
63
76
  this.pageSize = value
64
77
  this._emitChange()
@@ -3,6 +3,8 @@ import { customElement, property, query, } from 'lit/decorators.js';
3
3
  import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from '../types';
4
4
  export const TableCellElementTag = "spectric-table-cell"
5
5
  import { ColumnSettings, TableElement } from './table';
6
+ import { cache } from 'lit/directives/cache.js';
7
+ import { StyleInfo, styleMap } from 'lit/directives/style-map.js';
6
8
 
7
9
  interface CellProps<T> {
8
10
  column: ColumnSettings<T>
@@ -30,18 +32,15 @@ export class TableCellElement<T> extends LitElement implements CellProps<T> {
30
32
  column!: ColumnSettings<T>;
31
33
  columns!: ColumnSettings<T>[];
32
34
  table!: TableElement<T>
33
- styleRules: CSSStyleDeclaration;
35
+
34
36
  @query("td")
35
37
  td!: HTMLTableCellElement
36
- constructor() {
37
- super()
38
- this.styleRules = document.createElement('span').style;
39
- }
40
- protected updated(_changedProperties: PropertyValues): void {
41
- Object.assign(this.td.style, this.styleRules)
42
- }
38
+ styleRules: StyleInfo = { whiteSpace: "", width: "" };
43
39
  protected createRenderRoot(): HTMLElement | DocumentFragment {
44
40
  return this
41
+ }
42
+ protected updated(_changedProperties: PropertyValues): void {
43
+
45
44
  }
46
45
  _emitFilter(filter: FilterEvent<T>) {
47
46
  this.dispatchEvent(new CustomEvent<FilterEvent<T>>("filter", {
@@ -88,17 +87,20 @@ export class TableCellElement<T> extends LitElement implements CellProps<T> {
88
87
  if (this.column.filterable) {
89
88
  classes.push("filterable")
90
89
  }
91
- let filterButtons = html`<div class="table-cell-actions">
90
+
91
+ let filterButtons = cache(this.column.filterable
92
+ ? html`<div class="table-cell-actions">
92
93
  <spectric-button @click=${this._handleFilterOut} size="tiny" variant="text" icon tooltip="Filter Out Value">-</spectric-button>
93
94
  <spectric-button @click=${this._handleFilterFor} size="tiny" variant="text" icon tooltip="Filter For Value">+</spectric-button></div>`
95
+ : null
96
+ )
94
97
  this.styleRules = {
95
- ...this.styleRules,
96
98
  width: this.column.width ? this.column.width + "px" : "",
97
99
  whiteSpace: this.column.whiteSpace || ""
98
100
  }
99
101
  return html`
100
- <td>
101
- ${this.column.filterable ? filterButtons : null}
102
+ <td style=${styleMap(this.styleRules)}>
103
+ ${filterButtons}
102
104
  <div class=${classes.join(" ")}>${rendered}</div>
103
105
  </td>
104
106
  `
@@ -121,8 +121,6 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
121
121
  }
122
122
 
123
123
  private _handlePaginationChange = (e: CustomEvent<PaginationChangeProps>) => {
124
- e.preventDefault()
125
- e.stopPropagation()
126
124
  if (this.pagination) {
127
125
  let pagination = { ...this.pagination, ...e.detail }
128
126
 
@@ -159,7 +157,7 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
159
157
  }
160
158
  //@ts-ignore
161
159
  private __DO_NOT_USE_filter = () => {
162
- //This is only here to document events that bubble up from lower components
160
+ //This is only here to auto document events that bubble up from lower components
163
161
  this.dispatchEvent(new CustomEvent<FilterEvent<T>>("filter"))
164
162
  this.dispatchEvent(new CustomEvent<ColumnSettings<T>>("sortChange"))
165
163
  }
@@ -63,7 +63,7 @@ export class TooltipElement extends DisposableElement implements TooltipProps {
63
63
  position: TooltipPostionsTypes = "right";
64
64
  @property({ type: Number, reflect: true })
65
65
  maxWidth?: number = 300;
66
- private portalElement = document.createElement("div")
66
+ private portalElement!: HTMLDivElement
67
67
  private mouseLocation?: { left: number; top: number; };
68
68
  static styles?: CSSResultGroup | undefined = css`:host{max-height: 0px;
69
69
  max-width: 0px;
@@ -90,10 +90,14 @@ export class TooltipElement extends DisposableElement implements TooltipProps {
90
90
  }
91
91
  connectedCallback(): void {
92
92
  super.connectedCallback()
93
+ this.portalElement = document.createElement("div")
94
+ this.portalElement.className = "spectric-tooltip-portal"
93
95
  }
94
96
  disconnectedCallback(): void {
95
- super.disconnectedCallback()
97
+ super.disconnectedCallback();
96
98
  this.portalElement.remove()
99
+ //@ts-ignore
100
+ this.portalElement = undefined
97
101
  }
98
102
  private _getMousePosition = (ev: MouseEvent) => {
99
103
  this.mouseLocation = {
@@ -199,6 +203,7 @@ export class TooltipElement extends DisposableElement implements TooltipProps {
199
203
  protected render() {
200
204
  //We don't need to render anything here this is just a placeholder element the content is displayed in a portal attached to the body.
201
205
  // See showTooltip for the real rendering
206
+ return html`<!-- ToolTip -->`
202
207
  }
203
208
  }
204
209