@spectric/ui 0.0.12 → 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/README.MD +1 -1
- package/dist/classes/DisposibleElement.d.ts +2 -2
- package/dist/components/Button.d.ts +4 -4
- package/dist/components/pagination/pagination.d.ts +1 -0
- package/dist/components/table/cell.d.ts +4 -3
- package/dist/components/table/table.d.ts +6 -2
- package/dist/components/tooltip/tooltip.d.ts +1 -1
- package/dist/custom-elements.json +16 -8
- package/dist/index.es.js +1629 -1579
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +90 -86
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/classes/DisposibleElement.ts +8 -8
- package/src/components/Button.ts +7 -9
- package/src/components/pagination/pagination.ts +14 -1
- package/src/components/table/cell.ts +33 -31
- package/src/components/table/header.ts +8 -4
- package/src/components/table/sorting.ts +2 -2
- package/src/components/table/table.css +2 -0
- package/src/components/table/table.ts +16 -7
- package/src/components/tooltip/tooltip.ts +7 -2
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
spectric-input{--input-color: var(--spectric-input-color, #f4f4f4);--border-radius: var(--spectric-border-radius, .4em);--input-bottom: var(--spectric-input-bottom, var(--spectric-button-primary, #a8a8a8));--input-bottom-focused: var(--primary, #1ea7fd);--text-on-color: var(--spectric-text-on-color, #ffffff);--text-on-color-disabled: var(--spectric-text-on-color-disabled, #8d8d8d);--text-placeholder: rgba(22, 22, 22, .4);--text-primary: var(--spectric-text-primary, #161616);--text-secondary: var(--spectric-text-secondary, #525252)}spectric-input .inputWrapper{color:var(--text-secondary)}spectric-input .inputWrapper input{box-sizing:border-box;margin:0;vertical-align:baseline;font-size:.875rem;font-weight:400;line-height:1.28572;letter-spacing:.16px;outline:transparent solid 2px;outline-offset:-2px;border:none;padding:0 1rem;background-color:var(--input-color);color:var(--text-primary, #161616);font-family:inherit;inline-size:100%;block-size:2.5rem}spectric-input .inputWrapper .inputContainer:active:after,spectric-input .inputContainer:focus-within:after{border-bottom-color:var(--input-bottom-focused);width:calc(100% - 5px);transition:width .4s ease-in-out}spectric-input .inputWrapper input:read-only{background-color:transparent;border-bottom-color:var(--border-disabled)}spectric-input .inputContainer{position:relative;border-radius:var(--border-radius);overflow:hidden}spectric-input .inputContainer:after{content:"";width:0px;transition:background-color .4s cubic-bezier(.2,0,.38,.9),border-bottom-color .4s cubic-bezier(.2,0,.38,.9);border-bottom-color:var(--input-bottom);border-bottom-style:solid;border-bottom-width:1px;position:absolute;left:2.5px;bottom:0}spectric-input #helper-text{height:18px}spectric-input[variant=password] spectric-button{position:absolute;right:4px;bottom:3px}spectric-input .checkbox{display:flex;justify-self:center}spectric-query{font-family:monospace}spectric-query .autocomplete{color:var(--spectric-text-primary, #161616);border-radius:0em 0em var(--spectric-border-radius, .4em) var(--spectric-border-radius, .4em);background-color:var(--spectric-background, #ffffff);border:1px solid var(--spectric-background-hover, rgba(141, 141, 141, .12));max-height:300px;border-top:0px;margin:-18px 0 0;position:fixed;top:anchor(bottom);justify-self:anchor-center;text-align:center}spectric-query .autocomplete .optiontype{float:left;max-width:10px}spectric-query .autocomplete .label{position:absolute;right:0}spectric-query .autocomplete .option.active,spectric-query .autocomplete .option:hover{background-color:var(--spectric-background-hover, rgba(141, 141, 141, .12));border-bottom:1px solid var(--primary, #1ea7fd)}spectric-query .autocomplete .option{border-bottom:1px solid transparent;padding:8px}.query-bar-date-quick-select{display:flex;justify-content:space-evenly}spectric-pagination .spectric-pagination-container{display:flex;justify-content:space-between;align-items:center}spectric-pagination .spectric-pagination-text{flex-grow:1;text-align:center}spectric-table{display:flex;flex-direction:column;overflow:hidden}spectric-table .table-wrapper{overflow:auto;flex-grow:1;position:relative}spectric-table tr{text-align:center}spectric-table tr.odd{background-color:color-mix(in srgb,var(--spectric-primary, #1ea7fd),transparent 90%)}spectric-table tr:hover{background-color:color-mix(in srgb,var(--spectric-primary, #1ea7fd),transparent 70%)}spectric-table-header{display:table-header-group;font-weight:700;position:sticky;top:0;left:0;z-index:1;background:var(--spectric-background, #ffffff)}spectric-table-header td{vertical-align:middle}spectric-table tr{line-height:var(--rowHeight)}spectric-table td{height:var(--rowHeight)}spectric-table-header .header-contents{position:relative}spectric-table-header .header-contents .sort-direction{position:absolute;right:0}spectric-table-header .header-contents.sortable{cursor:pointer}spectric-table-header .header-contents.sortable:hover .sort-direction.none:before{content:"⮁"}spectric-table div[role=table]{display:table;min-width:100%}spectric-table-cell{display:contents;vertical-align:middle}spectric-table-cell td{position:relative}spectric-table td:hover:has(.filterable){border:1px solid var(--spectric-primary, #1ea7fd)}spectric-table td{border:1px solid transparent}spectric-table-cell .table-cell-actions{position:absolute;display:flex;width:100%;flex-direction:row-reverse;visibility:hidden;top:-10px}spectric-table-cell td:hover .table-cell-actions{visibility:unset}spectric-table .table-checkbox-single spectric-button{--button-border-radius: 50%}spectric-input.table-checkbox-single[checked] spectric-button{--text-on-color: transparent;border-radius:50%;position:relative}spectric-input.table-checkbox-single[checked] spectric-button:before{position:absolute;content:" ";height:50%;width:50%;left:25%;top:25%;border-radius:50%;z-index:1;box-shadow:0 0 0 4px var(--input-color)}spectric-table-body{display:table-row-group}spectric-table-virtual-body{display:contents}spectric-table-virtual-body .virtual-scroll-spacer td{padding:0;border:0px}.spectric-tooltip-portal{position:fixed;z-index:9999;pointer-events:none;--spectric-tooltip-background: color-mix(in srgb,var(--spectric-background-inverse,#f4f4f4) 100%,var(--spectric-primary,#1ea7fd) 90%) }.spectric-tooltip-portal .tooltip-container{display:flex;justify-content:center;align-items:center}.spectric-tooltip-portal.top .tooltip-container{flex-direction:column-reverse}.spectric-tooltip-portal.bottom .tooltip-container{flex-direction:column}.spectric-tooltip-portal.left .tooltip-container{flex-direction:row-reverse}.spectric-tooltip-portal .tooltip-content{background:var(--spectric-tooltip-background);border-radius:var(--spectric-border-radius,.4em);box-shadow:0 0 .01em .01em color-mix(in srgb,var(--spectric-background-hover,rgba(141, 141, 141, .12)) 90%,var(--spectric-text-on-color,#ffffff) 90%);padding:.2em;color:var(--spectric-text-on-color,#ffffff)}.spectric-tooltip-portal .tooltip-caret{background:var(--spectric-tooltip-background)}.spectric-tooltip-portal.top .tooltip-caret,.spectric-tooltip-portal.bottom .tooltip-caret{inline-size:.75rem;block-size:.374rem}.spectric-tooltip-portal.left .tooltip-caret,.spectric-tooltip-portal.right .tooltip-caret{inline-size:.375rem;block-size:.75rem}.spectric-tooltip-portal.top .tooltip-caret{clip-path:polygon(0 0,50% 100%,100% 0)}.spectric-tooltip-portal.bottom .tooltip-caret{clip-path:polygon(0 100%,50% 0,100% 100%)}.spectric-tooltip-portal.left .tooltip-caret{clip-path:polygon(0 0,100% 50%,0 100%)}.spectric-tooltip-portal.right .tooltip-caret{clip-path:polygon(0 50%,100% 0,100% 100%)}
|
|
1
|
+
spectric-input{--input-color: var(--spectric-input-color, #f4f4f4);--border-radius: var(--spectric-border-radius, .4em);--input-bottom: var(--spectric-input-bottom, var(--spectric-button-primary, #a8a8a8));--input-bottom-focused: var(--primary, #1ea7fd);--text-on-color: var(--spectric-text-on-color, #ffffff);--text-on-color-disabled: var(--spectric-text-on-color-disabled, #8d8d8d);--text-placeholder: rgba(22, 22, 22, .4);--text-primary: var(--spectric-text-primary, #161616);--text-secondary: var(--spectric-text-secondary, #525252)}spectric-input .inputWrapper{color:var(--text-secondary)}spectric-input .inputWrapper input{box-sizing:border-box;margin:0;vertical-align:baseline;font-size:.875rem;font-weight:400;line-height:1.28572;letter-spacing:.16px;outline:transparent solid 2px;outline-offset:-2px;border:none;padding:0 1rem;background-color:var(--input-color);color:var(--text-primary, #161616);font-family:inherit;inline-size:100%;block-size:2.5rem}spectric-input .inputWrapper .inputContainer:active:after,spectric-input .inputContainer:focus-within:after{border-bottom-color:var(--input-bottom-focused);width:calc(100% - 5px);transition:width .4s ease-in-out}spectric-input .inputWrapper input:read-only{background-color:transparent;border-bottom-color:var(--border-disabled)}spectric-input .inputContainer{position:relative;border-radius:var(--border-radius);overflow:hidden}spectric-input .inputContainer:after{content:"";width:0px;transition:background-color .4s cubic-bezier(.2,0,.38,.9),border-bottom-color .4s cubic-bezier(.2,0,.38,.9);border-bottom-color:var(--input-bottom);border-bottom-style:solid;border-bottom-width:1px;position:absolute;left:2.5px;bottom:0}spectric-input #helper-text{height:18px}spectric-input[variant=password] spectric-button{position:absolute;right:4px;bottom:3px}spectric-input .checkbox{display:flex;justify-self:center}spectric-query{font-family:monospace}spectric-query .autocomplete{color:var(--spectric-text-primary, #161616);border-radius:0em 0em var(--spectric-border-radius, .4em) var(--spectric-border-radius, .4em);background-color:var(--spectric-background, #ffffff);border:1px solid var(--spectric-background-hover, rgba(141, 141, 141, .12));max-height:300px;border-top:0px;margin:-18px 0 0;position:fixed;top:anchor(bottom);justify-self:anchor-center;text-align:center}spectric-query .autocomplete .optiontype{float:left;max-width:10px}spectric-query .autocomplete .label{position:absolute;right:0}spectric-query .autocomplete .option.active,spectric-query .autocomplete .option:hover{background-color:var(--spectric-background-hover, rgba(141, 141, 141, .12));border-bottom:1px solid var(--primary, #1ea7fd)}spectric-query .autocomplete .option{border-bottom:1px solid transparent;padding:8px}.query-bar-date-quick-select{display:flex;justify-content:space-evenly}spectric-pagination .spectric-pagination-container{display:flex;justify-content:space-between;align-items:center}spectric-pagination .spectric-pagination-text{flex-grow:1;text-align:center}spectric-table{display:flex;flex-direction:column;overflow:hidden}spectric-table .table-wrapper{overflow:auto;flex-grow:1;position:relative}spectric-table tr{text-align:center}spectric-table tr.odd{background-color:color-mix(in srgb,var(--spectric-primary, #1ea7fd),transparent 90%)}spectric-table tr:hover{background-color:color-mix(in srgb,var(--spectric-primary, #1ea7fd),transparent 70%)}spectric-table-header{display:table-header-group;font-weight:700;position:sticky;top:0;left:0;z-index:1;background:var(--spectric-background, #ffffff)}spectric-table-header td{vertical-align:middle}spectric-table tr{line-height:var(--rowHeight)}spectric-table td{height:var(--rowHeight)}spectric-table-header .header-contents{position:relative}spectric-table-header .header-contents .sort-direction{position:absolute;right:0;top:calc(50% - 8px)}spectric-table-header .header-contents.sortable{cursor:pointer;padding-right:15px}spectric-table-header .header-contents.sortable:hover .sort-direction.none:before{content:"⮁"}spectric-table div[role=table]{display:table;min-width:100%}spectric-table-cell{display:contents;vertical-align:middle}spectric-table-cell td{position:relative}spectric-table td:hover:has(.filterable){border:1px solid var(--spectric-primary, #1ea7fd)}spectric-table td{border:1px solid transparent}spectric-table-cell .table-cell-actions{position:absolute;display:flex;width:100%;flex-direction:row-reverse;visibility:hidden;top:-10px}spectric-table-cell td:hover .table-cell-actions{visibility:unset}spectric-table .table-checkbox-single spectric-button{--button-border-radius: 50%}spectric-input.table-checkbox-single[checked] spectric-button{--text-on-color: transparent;border-radius:50%;position:relative}spectric-input.table-checkbox-single[checked] spectric-button:before{position:absolute;content:" ";height:50%;width:50%;left:25%;top:25%;border-radius:50%;z-index:1;box-shadow:0 0 0 4px var(--input-color)}spectric-table-body{display:table-row-group}spectric-table-virtual-body{display:contents}spectric-table-virtual-body .virtual-scroll-spacer td{padding:0;border:0px}.spectric-tooltip-portal{position:fixed;z-index:9999;pointer-events:none;--spectric-tooltip-background: color-mix(in srgb,var(--spectric-background-inverse,#f4f4f4) 100%,var(--spectric-primary,#1ea7fd) 90%) }.spectric-tooltip-portal .tooltip-container{display:flex;justify-content:center;align-items:center}.spectric-tooltip-portal.top .tooltip-container{flex-direction:column-reverse}.spectric-tooltip-portal.bottom .tooltip-container{flex-direction:column}.spectric-tooltip-portal.left .tooltip-container{flex-direction:row-reverse}.spectric-tooltip-portal .tooltip-content{background:var(--spectric-tooltip-background);border-radius:var(--spectric-border-radius,.4em);box-shadow:0 0 .01em .01em color-mix(in srgb,var(--spectric-background-hover,rgba(141, 141, 141, .12)) 90%,var(--spectric-text-on-color,#ffffff) 90%);padding:.2em;color:var(--spectric-text-on-color,#ffffff)}.spectric-tooltip-portal .tooltip-caret{background:var(--spectric-tooltip-background)}.spectric-tooltip-portal.top .tooltip-caret,.spectric-tooltip-portal.bottom .tooltip-caret{inline-size:.75rem;block-size:.374rem}.spectric-tooltip-portal.left .tooltip-caret,.spectric-tooltip-portal.right .tooltip-caret{inline-size:.375rem;block-size:.75rem}.spectric-tooltip-portal.top .tooltip-caret{clip-path:polygon(0 0,50% 100%,100% 0)}.spectric-tooltip-portal.bottom .tooltip-caret{clip-path:polygon(0 100%,50% 0,100% 100%)}.spectric-tooltip-portal.left .tooltip-caret{clip-path:polygon(0 0,100% 50%,0 100%)}.spectric-tooltip-portal.right .tooltip-caret{clip-path:polygon(0 50%,100% 0,100% 100%)}
|
package/package.json
CHANGED
|
@@ -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
|
|
package/src/components/Button.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSResultGroup, html
|
|
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
|
|
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
|
-
|
|
70
|
-
super
|
|
71
|
-
this.
|
|
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,50 +32,47 @@ 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
|
-
|
|
35
|
+
|
|
34
36
|
@query("td")
|
|
35
37
|
td!: HTMLTableCellElement
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this
|
|
38
|
+
styleRules: StyleInfo = { whiteSpace: "", width: "" };
|
|
39
|
+
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
40
|
+
return this
|
|
39
41
|
}
|
|
40
42
|
protected updated(_changedProperties: PropertyValues): void {
|
|
41
|
-
|
|
43
|
+
|
|
42
44
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
_emitFilter(filter: FilterEvent<T>) {
|
|
46
|
+
this.dispatchEvent(new CustomEvent<FilterEvent<T>>("filter", {
|
|
47
|
+
composed: true,
|
|
48
|
+
bubbles: true,
|
|
49
|
+
detail: filter
|
|
50
|
+
}))
|
|
45
51
|
}
|
|
46
52
|
_handleFilterOut = () => {
|
|
47
53
|
let value = undefined;
|
|
48
54
|
if (this.column.key && typeof this.row === "object") {
|
|
49
55
|
value = rowGetValue(this.row as Record<any, any>, this.column.key)
|
|
50
56
|
}
|
|
51
|
-
this.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
column: this.column
|
|
59
|
-
}
|
|
60
|
-
}))
|
|
57
|
+
this._emitFilter({
|
|
58
|
+
include: false,
|
|
59
|
+
row: this.row,
|
|
60
|
+
value,
|
|
61
|
+
column: this.column
|
|
62
|
+
})
|
|
63
|
+
|
|
61
64
|
}
|
|
62
65
|
_handleFilterFor = () => {
|
|
63
66
|
let value = undefined;
|
|
64
67
|
if (this.column.key && typeof this.row === "object") {
|
|
65
68
|
value = rowGetValue(this.row as Record<any, any>, this.column.key)
|
|
66
69
|
}
|
|
67
|
-
this.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
value,
|
|
74
|
-
column: this.column
|
|
75
|
-
}
|
|
76
|
-
}))
|
|
70
|
+
this._emitFilter({
|
|
71
|
+
include: true,
|
|
72
|
+
row: this.row,
|
|
73
|
+
value,
|
|
74
|
+
column: this.column
|
|
75
|
+
})
|
|
77
76
|
}
|
|
78
77
|
protected render(): unknown {
|
|
79
78
|
let rendered
|
|
@@ -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
|
-
|
|
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
|
-
${
|
|
102
|
+
<td style=${styleMap(this.styleRules)}>
|
|
103
|
+
${filterButtons}
|
|
102
104
|
<div class=${classes.join(" ")}>${rendered}</div>
|
|
103
105
|
</td>
|
|
104
106
|
`
|
|
@@ -30,11 +30,15 @@ export class TableHeaderElement<T> extends LitElement implements HeaderProps<T>
|
|
|
30
30
|
if (column.sortDirection === TableSortDirection.none || column.sortDirection === undefined) {
|
|
31
31
|
column.sortDirection = TableSortDirection.ascending
|
|
32
32
|
} else if (column.sortDirection === TableSortDirection.ascending) {
|
|
33
|
-
column.sortDirection = TableSortDirection.
|
|
34
|
-
} else if (column.sortDirection === TableSortDirection.
|
|
33
|
+
column.sortDirection = TableSortDirection.descending
|
|
34
|
+
} else if (column.sortDirection === TableSortDirection.descending) {
|
|
35
35
|
column.sortDirection = TableSortDirection.none
|
|
36
36
|
}
|
|
37
|
-
this.dispatchEvent(new CustomEvent<ColumnSettings<T>>("sortChange", {
|
|
37
|
+
this.dispatchEvent(new CustomEvent<ColumnSettings<T>>("sortChange", {
|
|
38
|
+
composed: true,
|
|
39
|
+
bubbles: true,
|
|
40
|
+
detail: column
|
|
41
|
+
}))
|
|
38
42
|
}
|
|
39
43
|
protected render(): unknown {
|
|
40
44
|
return html`
|
|
@@ -48,7 +52,7 @@ export class TableHeaderElement<T> extends LitElement implements HeaderProps<T>
|
|
|
48
52
|
classes.push("sortable")
|
|
49
53
|
}
|
|
50
54
|
let columnWidth = column.width ? `width:${column.width}px;` : ""
|
|
51
|
-
let sortDirection = column.sortDirection === TableSortDirection.ascending ? `🠉` : column.sortDirection == TableSortDirection.
|
|
55
|
+
let sortDirection = column.sortDirection === TableSortDirection.ascending ? `🠉` : column.sortDirection == TableSortDirection.descending ? `🠋` : ``
|
|
52
56
|
let sortClass = column.sortDirection || TableSortDirection.none
|
|
53
57
|
return html`
|
|
54
58
|
<td @click=${() => this._handleSortChange(column)} style="${columnWidth}">
|
|
@@ -19,12 +19,12 @@ export const createSortChain = <T>(sorts: ColumnSettings<T>[]) => {
|
|
|
19
19
|
if (typeof v1 === "number" || typeof v1 === "bigint" || typeof v1 === "boolean") {
|
|
20
20
|
//@ts-ignore
|
|
21
21
|
let sort: number = v1 - v2 as unknown as number
|
|
22
|
-
if (sortDirection === TableSortDirection.
|
|
22
|
+
if (sortDirection === TableSortDirection.descending) {
|
|
23
23
|
sort = sort * -1
|
|
24
24
|
}
|
|
25
25
|
return sort
|
|
26
26
|
} else if (typeof v1 === "string") {
|
|
27
|
-
return v1.localeCompare(v2) * (sortDirection === TableSortDirection.
|
|
27
|
+
return v1.localeCompare(v2) * (sortDirection === TableSortDirection.descending ? -1 : 1)
|
|
28
28
|
}
|
|
29
29
|
once(() => { console.error(`Unable to sort type ${typeof v1}`) })
|
|
30
30
|
return undefined
|
|
@@ -43,9 +43,11 @@ spectric-table-header .header-contents {
|
|
|
43
43
|
spectric-table-header .header-contents .sort-direction {
|
|
44
44
|
position: absolute;
|
|
45
45
|
right: 0;
|
|
46
|
+
top: calc(50% - 8px)
|
|
46
47
|
}
|
|
47
48
|
spectric-table-header .header-contents.sortable {
|
|
48
49
|
cursor: pointer;
|
|
50
|
+
padding-right:15px
|
|
49
51
|
}
|
|
50
52
|
spectric-table-header .header-contents.sortable:hover .sort-direction.none::before
|
|
51
53
|
{
|
|
@@ -28,7 +28,7 @@ export enum TableSortOption {
|
|
|
28
28
|
export type TableSortOptionTypes = `${TableSortOption}`
|
|
29
29
|
export enum TableSortDirection {
|
|
30
30
|
ascending = "ascending",
|
|
31
|
-
|
|
31
|
+
descending = "descending",
|
|
32
32
|
none = "none"
|
|
33
33
|
}
|
|
34
34
|
export type TableSortDirectionTypes = `${TableSortDirection}`
|
|
@@ -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
|
|
|
@@ -132,6 +130,7 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
|
|
|
132
130
|
}
|
|
133
131
|
this.pagination = pagination
|
|
134
132
|
}
|
|
133
|
+
this.dispatchEvent(new CustomEvent<PaginationChangeProps>("paginationChange", { detail: e.detail }))
|
|
135
134
|
this._emitChange()
|
|
136
135
|
};
|
|
137
136
|
private _handleSortChange = (e: CustomEvent<ColumnSettings<T>>) => {
|
|
@@ -158,22 +157,30 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
|
|
|
158
157
|
}
|
|
159
158
|
//@ts-ignore
|
|
160
159
|
private __DO_NOT_USE_filter = () => {
|
|
161
|
-
//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
|
|
162
161
|
this.dispatchEvent(new CustomEvent<FilterEvent<T>>("filter"))
|
|
162
|
+
this.dispatchEvent(new CustomEvent<ColumnSettings<T>>("sortChange"))
|
|
163
163
|
}
|
|
164
164
|
@state()
|
|
165
165
|
private selected: T[] = [];
|
|
166
166
|
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
167
167
|
return this
|
|
168
168
|
}
|
|
169
|
+
deselectAll() {
|
|
170
|
+
this.selected = []
|
|
171
|
+
this.dispatchEvent(new CustomEvent("selected", { detail: this.selected }))
|
|
172
|
+
}
|
|
173
|
+
selectAll() {
|
|
174
|
+
this.selected = [...this.data]
|
|
175
|
+
this.dispatchEvent(new CustomEvent("selected", { detail: this.selected }))
|
|
176
|
+
}
|
|
169
177
|
_handleSelectAllChange = (e: DomEvent<HTMLInputElement>) => {
|
|
170
178
|
e.stopPropagation()
|
|
171
179
|
if (e.target.checked) {
|
|
172
|
-
this.
|
|
180
|
+
this.selectAll()
|
|
173
181
|
} else {
|
|
174
|
-
this.
|
|
182
|
+
this.deselectAll()
|
|
175
183
|
}
|
|
176
|
-
this.dispatchEvent(new CustomEvent("selected", { detail: this.selected }))
|
|
177
184
|
}
|
|
178
185
|
protected update(changedProperties: PropertyValues): void {
|
|
179
186
|
if (changedProperties.has("select")) {
|
|
@@ -235,7 +242,9 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
|
|
|
235
242
|
|
|
236
243
|
interface TableEvents {
|
|
237
244
|
'change': (event: CustomEvent<TableDataOptions<any>>) => void;
|
|
245
|
+
'paginationChange': (event: CustomEvent<PaginationChangeProps>) => void;
|
|
238
246
|
'filter': (event: CustomEvent<FilterEvent<any>>) => void;
|
|
247
|
+
'sortChange': (event: CustomEvent<ColumnSettings<any>>) => void;
|
|
239
248
|
}
|
|
240
249
|
|
|
241
250
|
declare global {
|
|
@@ -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
|
|
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
|
|