@spectric/ui 0.0.11 → 0.0.13
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 +4 -2
- package/dist/components/Bitdisplay.d.ts +4 -4
- package/dist/components/Button.d.ts +1 -1
- package/dist/components/Header.d.ts +1 -1
- package/dist/components/input.d.ts +13 -12
- package/dist/components/splitview/splitview.d.ts +5 -5
- package/dist/components/table/body.d.ts +2 -1
- package/dist/components/table/cell.d.ts +2 -0
- package/dist/components/table/table.d.ts +14 -6
- package/dist/components/table/virtualBody.d.ts +49 -0
- package/dist/components/tooltip/tooltip.d.ts +15 -10
- package/dist/custom-elements.json +31 -9
- package/dist/index.es.js +1960 -1784
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +124 -91
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/classes/DisposibleElement.ts +15 -9
- package/src/components/Bitdisplay.ts +7 -7
- package/src/components/Button.ts +1 -1
- package/src/components/Header.ts +1 -1
- package/src/components/input.ts +18 -14
- package/src/components/splitview/splitview.ts +5 -5
- package/src/components/table/body.ts +13 -5
- package/src/components/table/cell.ts +24 -21
- package/src/components/table/header.ts +15 -6
- package/src/components/table/sorting.ts +2 -2
- package/src/components/table/table.css +12 -6
- package/src/components/table/table.ts +60 -20
- package/src/components/table/virtualBody.css +13 -0
- package/src/components/table/virtualBody.ts +127 -0
- package/src/components/tooltip/tooltip.ts +36 -30
- package/src/docs/HTML-Vue-Python Integration.mdx +3 -3
- package/src/docs/html-include.png +0 -0
- package/src/docs/vue-example.png +0 -0
- package/src/docs/vue-include.png +0 -0
- package/src/stories/BitDisplay.stories.ts +2 -0
- package/src/stories/fixtures/data.ts +1 -1
- package/src/stories/pagination.stories.ts +2 -1
- package/src/stories/table.stories.ts +4 -2
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { html, LitElement, TemplateResult } from 'lit';
|
|
1
|
+
import { html, LitElement, PropertyValues, render, TemplateResult } from 'lit';
|
|
2
2
|
import "../pagination";
|
|
3
3
|
import "./header"
|
|
4
4
|
import "./body"
|
|
5
5
|
import { customElement, property, state, } from 'lit/decorators.js';
|
|
6
6
|
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from '../types';
|
|
7
|
+
import "./virtualBody"
|
|
7
8
|
import "./table.css"
|
|
8
9
|
export const TableElementTag = "spectric-table"
|
|
9
10
|
import { spreadProps } from '../../utils/spread';
|
|
10
11
|
import { PaginationChangeProps, PaginationProps } from '../pagination';
|
|
11
12
|
import { FilterEvent } from './cell';
|
|
12
13
|
import { createSortChain } from './sorting';
|
|
14
|
+
|
|
13
15
|
export type { TableProps, TableEvents }
|
|
14
16
|
|
|
15
17
|
export type DomRenderable = HTMLElement | TemplateResult | string | number | null
|
|
@@ -26,7 +28,7 @@ export enum TableSortOption {
|
|
|
26
28
|
export type TableSortOptionTypes = `${TableSortOption}`
|
|
27
29
|
export enum TableSortDirection {
|
|
28
30
|
ascending = "ascending",
|
|
29
|
-
|
|
31
|
+
descending = "descending",
|
|
30
32
|
none = "none"
|
|
31
33
|
}
|
|
32
34
|
export type TableSortDirectionTypes = `${TableSortDirection}`
|
|
@@ -45,7 +47,7 @@ export type ColumnSettings<T> = {
|
|
|
45
47
|
/**
|
|
46
48
|
* Render function to render a table cell for displaying custom html
|
|
47
49
|
*/
|
|
48
|
-
render?: (row: T, table: TableElement<T>) => DomRenderable
|
|
50
|
+
render?: (row: T, index: number, table: TableElement<T>) => DomRenderable
|
|
49
51
|
/**
|
|
50
52
|
* Custom comparator function for sorting
|
|
51
53
|
*/
|
|
@@ -60,6 +62,7 @@ interface TableProps<T> extends TableDataOptions<T> {
|
|
|
60
62
|
data: T[]
|
|
61
63
|
select: TableSelectOptionsTypes
|
|
62
64
|
sort?: TableSortOptionTypes
|
|
65
|
+
rowHeight?: number
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
type DomEvent<T> = Event & {
|
|
@@ -83,6 +86,12 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
|
|
|
83
86
|
@property({ type: String, reflect: true })
|
|
84
87
|
sort: TableSortOptionTypes = TableSortOption.single;
|
|
85
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Needed for virtualization
|
|
91
|
+
*/
|
|
92
|
+
@property({ type: Number, reflect: true })
|
|
93
|
+
rowHeight: number = 25;
|
|
94
|
+
|
|
86
95
|
static getDefaultDataSorterAndPaginatior<T>(data: T[]) {
|
|
87
96
|
return (props: TableDataOptions<T>) => {
|
|
88
97
|
let sorts = props.columns.filter(column => column.sortable && column.sortDirection && column.sortDirection !== TableSortDirection.none)
|
|
@@ -123,6 +132,7 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
|
|
|
123
132
|
}
|
|
124
133
|
this.pagination = pagination
|
|
125
134
|
}
|
|
135
|
+
this.dispatchEvent(new CustomEvent<PaginationChangeProps>("paginationChange", { detail: e.detail }))
|
|
126
136
|
this._emitChange()
|
|
127
137
|
};
|
|
128
138
|
private _handleSortChange = (e: CustomEvent<ColumnSettings<T>>) => {
|
|
@@ -151,20 +161,37 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
|
|
|
151
161
|
private __DO_NOT_USE_filter = () => {
|
|
152
162
|
//This is only here to document events that bubble up from lower components
|
|
153
163
|
this.dispatchEvent(new CustomEvent<FilterEvent<T>>("filter"))
|
|
164
|
+
this.dispatchEvent(new CustomEvent<ColumnSettings<T>>("sortChange"))
|
|
154
165
|
}
|
|
155
166
|
@state()
|
|
156
167
|
private selected: T[] = [];
|
|
157
168
|
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
158
169
|
return this
|
|
159
170
|
}
|
|
171
|
+
deselectAll() {
|
|
172
|
+
this.selected = []
|
|
173
|
+
this.dispatchEvent(new CustomEvent("selected", { detail: this.selected }))
|
|
174
|
+
}
|
|
175
|
+
selectAll() {
|
|
176
|
+
this.selected = [...this.data]
|
|
177
|
+
this.dispatchEvent(new CustomEvent("selected", { detail: this.selected }))
|
|
178
|
+
}
|
|
160
179
|
_handleSelectAllChange = (e: DomEvent<HTMLInputElement>) => {
|
|
161
180
|
e.stopPropagation()
|
|
162
181
|
if (e.target.checked) {
|
|
163
|
-
this.
|
|
182
|
+
this.selectAll()
|
|
164
183
|
} else {
|
|
165
|
-
this.
|
|
184
|
+
this.deselectAll()
|
|
166
185
|
}
|
|
167
|
-
|
|
186
|
+
}
|
|
187
|
+
protected update(changedProperties: PropertyValues): void {
|
|
188
|
+
if (changedProperties.has("select")) {
|
|
189
|
+
if (this.select === "single" && this.selected.length > 1) {
|
|
190
|
+
this.selected = [this.selected[0]]
|
|
191
|
+
this.dispatchEvent(new CustomEvent("selected", { detail: [...this.selected] }))
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
super.update(changedProperties)
|
|
168
195
|
}
|
|
169
196
|
protected render(): unknown {
|
|
170
197
|
let columns = this.columns.filter(column => !column.hidden)
|
|
@@ -172,31 +199,42 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
|
|
|
172
199
|
columns.unshift({
|
|
173
200
|
title: this.select === "multi" ? html`<spectric-input variant="checkbox" @change=${this._handleSelectAllChange} .helperText=${"Select All"}></spectric-input>` : null,
|
|
174
201
|
render: (row) => {
|
|
175
|
-
|
|
202
|
+
let container = document.createElement("div")
|
|
203
|
+
let checked = this.selected.includes(row)
|
|
204
|
+
let template = html`<spectric-input variant="checkbox" class="table-checkbox-${this.select}" ${spreadProps({ checked })} @change=${(e: DomEvent<HTMLInputElement>) => {
|
|
176
205
|
e.stopPropagation()
|
|
177
|
-
|
|
178
|
-
|
|
206
|
+
let index = this.selected.findIndex(value => value === row)
|
|
207
|
+
if (e.target.checked && index !== -1) {
|
|
208
|
+
return
|
|
209
|
+
}
|
|
210
|
+
else if (!e.target.checked && index === -1) {
|
|
211
|
+
return
|
|
212
|
+
}
|
|
213
|
+
else if (!e.target.checked && index !== -1) {
|
|
214
|
+
this.selected.splice(index, 1)
|
|
179
215
|
}
|
|
180
216
|
if (e.target.checked) {
|
|
181
|
-
this.
|
|
182
|
-
|
|
183
|
-
} else {
|
|
184
|
-
let index = this.selected.findIndex(value => value === row)
|
|
185
|
-
if (index !== -1) {
|
|
186
|
-
this.selected.splice(index, 1)
|
|
187
|
-
this.dispatchEvent(new CustomEvent("selected", { detail: this.selected }))
|
|
217
|
+
if (this.select === "single") {
|
|
218
|
+
this.selected = []
|
|
188
219
|
}
|
|
220
|
+
this.selected.push(row)
|
|
189
221
|
}
|
|
222
|
+
this.dispatchEvent(new CustomEvent("selected", { detail: [...this.selected] }))
|
|
190
223
|
}}></spectric-input>`
|
|
224
|
+
render(template, container)
|
|
225
|
+
return template
|
|
191
226
|
}
|
|
192
227
|
})
|
|
193
228
|
}
|
|
194
|
-
|
|
229
|
+
const tdBorderAndPadding = 4;
|
|
195
230
|
return html`
|
|
196
|
-
<div class="table-wrapper">
|
|
231
|
+
<div class="table-wrapper" style="--rowHeight:${this.rowHeight - tdBorderAndPadding}px">
|
|
197
232
|
<div role="table">
|
|
198
233
|
<spectric-table-header .columns=${columns} @sortChange=${this._handleSortChange}></spectric-table-header>
|
|
199
|
-
|
|
234
|
+
${this.rowHeight >= 25 && this.data.length >= 100 ?
|
|
235
|
+
html`<spectric-table-virtual-body .columns=${columns} .data=${this.data} .table=${this} .rowHeight=${this.rowHeight}></spectric-table-virtual-body>` :
|
|
236
|
+
html`<spectric-table-body .columns=${columns} .data=${this.data} .table=${this}></spectric-table-body>`
|
|
237
|
+
}
|
|
200
238
|
</div>
|
|
201
239
|
</div>
|
|
202
240
|
${this.pagination ? html`<spectric-pagination ${spreadProps(this.pagination)} @change=${this._handlePaginationChange}></spectric-pagination>` : null}
|
|
@@ -205,8 +243,10 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
|
|
|
205
243
|
}
|
|
206
244
|
|
|
207
245
|
interface TableEvents {
|
|
208
|
-
'change': (event: CustomEvent<
|
|
246
|
+
'change': (event: CustomEvent<TableDataOptions<any>>) => void;
|
|
247
|
+
'paginationChange': (event: CustomEvent<PaginationChangeProps>) => void;
|
|
209
248
|
'filter': (event: CustomEvent<FilterEvent<any>>) => void;
|
|
249
|
+
'sortChange': (event: CustomEvent<ColumnSettings<any>>) => void;
|
|
210
250
|
}
|
|
211
251
|
|
|
212
252
|
declare global {
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import { customElement, property, } from 'lit/decorators.js';
|
|
3
|
+
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from '../types';
|
|
4
|
+
export const TableBodyElementTag = "spectric-table-virtual-body"
|
|
5
|
+
import "./cell"
|
|
6
|
+
import { ColumnSettings, TableElement } from './table';
|
|
7
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
8
|
+
import { DisposableElement } from '../../classes/DisposibleElement';
|
|
9
|
+
import "./virtualBody.css"
|
|
10
|
+
interface BodyProps<T> {
|
|
11
|
+
columns: ColumnSettings<T>[]
|
|
12
|
+
data: T[]
|
|
13
|
+
rowHeight: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Table Body Element
|
|
19
|
+
*/
|
|
20
|
+
@customElement(TableBodyElementTag)
|
|
21
|
+
export class TableVirtualBodyElement<T> extends DisposableElement implements BodyProps<T> {
|
|
22
|
+
@property({ type: Array, attribute: false })
|
|
23
|
+
data: T[] = [];
|
|
24
|
+
@property({ type: Array, attribute: false })
|
|
25
|
+
columns: ColumnSettings<T>[] = [];
|
|
26
|
+
@property({ type: Number, attribute: false })
|
|
27
|
+
rowHeight: number = 30;
|
|
28
|
+
|
|
29
|
+
@property({ type: Number, state: true })
|
|
30
|
+
startIndex: number = 0
|
|
31
|
+
|
|
32
|
+
table!: TableElement<T>
|
|
33
|
+
constructor() {
|
|
34
|
+
super()
|
|
35
|
+
this.addDisposableListener(() => this.table.querySelector(".table-wrapper")!, "scroll", () => {
|
|
36
|
+
const scrollTop = this.table.querySelector(".table-wrapper")!.scrollTop;
|
|
37
|
+
requestAnimationFrame(() => {
|
|
38
|
+
this.startIndex = Math.floor(scrollTop / this.rowHeight);
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
protected firstUpdated(): void {
|
|
43
|
+
this.columns.forEach(col => {
|
|
44
|
+
if (!col.width) {
|
|
45
|
+
console.warn("When using virtual scrolling it is recomended to set the width of the columns to prevent columns widths from jittering during scroll")
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
50
|
+
return this
|
|
51
|
+
}
|
|
52
|
+
protected render(): unknown {
|
|
53
|
+
let totalRows = this.data.length
|
|
54
|
+
let buffer = 10 // Have a buffer of rows to prevent column jitter
|
|
55
|
+
let headerHeight = this.table.querySelector("spectric-table-header")!.clientHeight
|
|
56
|
+
let viewport = this.table.querySelector(".table-wrapper")!
|
|
57
|
+
let startIndex = Math.max(this.startIndex - buffer, 0) //pad the front with 10 rows
|
|
58
|
+
const rowsThatFit = Math.ceil((viewport.clientHeight - headerHeight) / this.rowHeight);
|
|
59
|
+
const endIndex = Math.min(startIndex + rowsThatFit + buffer, totalRows);
|
|
60
|
+
const visibleRows = endIndex - startIndex
|
|
61
|
+
let totalHeight = totalRows * this.rowHeight
|
|
62
|
+
let beforeHeight = (startIndex * this.rowHeight) + (viewport.scrollTop - (startIndex * this.rowHeight))
|
|
63
|
+
if (endIndex === totalRows) {
|
|
64
|
+
beforeHeight = (startIndex * this.rowHeight)
|
|
65
|
+
}
|
|
66
|
+
let visibleHeight = (visibleRows * this.rowHeight)
|
|
67
|
+
let afterHeight = totalHeight - beforeHeight - visibleHeight
|
|
68
|
+
let spacerElementBefore = this.startIndex != 0 ? html`
|
|
69
|
+
<tr style="height:${beforeHeight}px" class="virtual-scroll-spacer">
|
|
70
|
+
<td colspan="${this.columns.length}"></td></tr>` : null
|
|
71
|
+
|
|
72
|
+
let spacerElementAfter = html`
|
|
73
|
+
<tr style="height:${afterHeight}px" class="virtual-scroll-spacer">
|
|
74
|
+
<td colspan="${this.columns.length}"></td></tr>`
|
|
75
|
+
return html`
|
|
76
|
+
<div style="height:${totalHeight}px;position: absolute;overflow-x: hidden;overflow-y: hidden;z-index:-1;width:1px;"></div>
|
|
77
|
+
<tbody>
|
|
78
|
+
${spacerElementBefore}
|
|
79
|
+
</tbody>
|
|
80
|
+
<div style="display:table-row-group;max-height:${visibleHeight}px; overflow:hidden;">
|
|
81
|
+
|
|
82
|
+
${repeat(this.data.slice(Math.max(startIndex, 0), endIndex), (row, index) => html`
|
|
83
|
+
<tr class="${(index + startIndex) % 2 === 0 ? "odd" : ""}">
|
|
84
|
+
${repeat(this.columns, (col) => {
|
|
85
|
+
return html`<spectric-table-cell .column=${col} .row=${row} .index=${index + startIndex} .columns=${this.columns}></spectric-table-cell>`
|
|
86
|
+
})}
|
|
87
|
+
</tr>`)
|
|
88
|
+
}
|
|
89
|
+
</div>
|
|
90
|
+
<tbody>
|
|
91
|
+
${afterHeight > 0 ? spacerElementAfter : null}
|
|
92
|
+
</tbody>
|
|
93
|
+
|
|
94
|
+
`
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
interface TableBodyEvents {
|
|
101
|
+
//'sort': (event: CustomEvent<ColumnSettings<any>>) => void; //TODO sort events
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
declare global {
|
|
105
|
+
interface HTMLElementTagNameMap {
|
|
106
|
+
[TableBodyElementTag]: HTMLElementTagWithEvents<TableVirtualBodyElement<any>, TableBodyEvents>
|
|
107
|
+
|
|
108
|
+
}
|
|
109
|
+
namespace JSX {
|
|
110
|
+
interface IntrinsicElements {
|
|
111
|
+
/**
|
|
112
|
+
* @see {@link DialogElement}
|
|
113
|
+
*/
|
|
114
|
+
[TableBodyElementTag]: ReactElementWithPropsAndEvents<TableVirtualBodyElement<any>, BodyProps<any>, TableBodyEvents>;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
namespace React {
|
|
118
|
+
namespace JSX {
|
|
119
|
+
interface IntrinsicElements {
|
|
120
|
+
/**
|
|
121
|
+
* @see {@link DialogElement}
|
|
122
|
+
*/
|
|
123
|
+
[TableBodyElementTag]: ReactElementWithPropsAndEvents<TableVirtualBodyElement<any>, BodyProps<any>, TableBodyEvents>
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -3,8 +3,9 @@ import { customElement, property } from 'lit/decorators.js';
|
|
|
3
3
|
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from '../types';
|
|
4
4
|
import "./tooltip.css"
|
|
5
5
|
export const TooltipElementTag = "spectric-tooltip"
|
|
6
|
-
import { css, CSSResultGroup, html,
|
|
6
|
+
import { css, CSSResultGroup, html, render } from "lit-element";
|
|
7
7
|
import { DomRenderable } from "../table";
|
|
8
|
+
import { DisposableElement } from '../../classes/DisposibleElement';
|
|
8
9
|
export type { TooltipProps, TooltipEvents }
|
|
9
10
|
export enum TooltipPostions {
|
|
10
11
|
top = "top",
|
|
@@ -19,11 +20,11 @@ interface TooltipProps {
|
|
|
19
20
|
/**
|
|
20
21
|
* How long you need to hover before the tooltip displays
|
|
21
22
|
*/
|
|
22
|
-
delay
|
|
23
|
+
delay?: number;
|
|
23
24
|
/**
|
|
24
25
|
* How long the fade in animation should run
|
|
25
26
|
*/
|
|
26
|
-
animationDuration
|
|
27
|
+
animationDuration?: number;
|
|
27
28
|
/**
|
|
28
29
|
* Tooltip contents
|
|
29
30
|
*/
|
|
@@ -31,18 +32,18 @@ interface TooltipProps {
|
|
|
31
32
|
/**
|
|
32
33
|
* Where to anchor the tooltip
|
|
33
34
|
*/
|
|
34
|
-
position
|
|
35
|
+
position?: TooltipPostionsTypes
|
|
35
36
|
/**
|
|
36
|
-
* Sets a max width for the contents
|
|
37
|
+
* Sets a max width for the contents you can disable this by setting to 0 or -1
|
|
37
38
|
*/
|
|
38
39
|
maxWidth?: number
|
|
39
40
|
/**
|
|
40
|
-
* Container the tool tip will be attached to.
|
|
41
|
+
* Container the tool tip will be attached to.
|
|
41
42
|
*/
|
|
42
43
|
portalTarget?: HTMLElement
|
|
43
44
|
|
|
44
45
|
/**
|
|
45
|
-
* The element that triggers the tooltip.
|
|
46
|
+
* The element that triggers the tooltip. This is used for special cases like in the shadow dom if you want to target a host element instead of the immediate parent element
|
|
46
47
|
*/
|
|
47
48
|
triggerTarget?: HTMLElement
|
|
48
49
|
}
|
|
@@ -51,7 +52,7 @@ interface TooltipProps {
|
|
|
51
52
|
* Spectric tooltip will add a tooltip to any container
|
|
52
53
|
*/
|
|
53
54
|
@customElement(TooltipElementTag)
|
|
54
|
-
export class TooltipElement extends
|
|
55
|
+
export class TooltipElement extends DisposableElement implements TooltipProps {
|
|
55
56
|
@property({ type: Number, reflect: true })
|
|
56
57
|
delay: number = 100;
|
|
57
58
|
@property({ type: Number, reflect: true })
|
|
@@ -72,25 +73,26 @@ export class TooltipElement extends LitElement implements TooltipProps {
|
|
|
72
73
|
portalTarget: HTMLElement = document.body
|
|
73
74
|
private timer?: number;
|
|
74
75
|
private open: boolean = false;
|
|
75
|
-
mouseframe?: number;
|
|
76
|
+
private mouseframe?: number;
|
|
77
|
+
/**
|
|
78
|
+
* @default parentElement
|
|
79
|
+
*/
|
|
76
80
|
@property({ attribute: false })
|
|
77
|
-
triggerTarget
|
|
81
|
+
triggerTarget!: HTMLElement;
|
|
78
82
|
private get target() {
|
|
79
83
|
return this.triggerTarget || this.parentElement
|
|
80
84
|
}
|
|
85
|
+
constructor() {
|
|
86
|
+
super()
|
|
87
|
+
this.addDisposableListener(() => this.target, "mousemove", this._getMousePosition)
|
|
88
|
+
this.addDisposableListener(() => this.target, "mouseover", this.showToolTip)
|
|
89
|
+
this.addDisposableListener(() => this.target, "mouseleave", this._hideTooltip)
|
|
90
|
+
}
|
|
81
91
|
connectedCallback(): void {
|
|
82
92
|
super.connectedCallback()
|
|
83
|
-
if (this.target) {
|
|
84
|
-
this.target.addEventListener("mousemove", this._getMousePosition)
|
|
85
|
-
this.target.addEventListener("mouseover", this.showToolTip)
|
|
86
|
-
this.target.addEventListener("mouseleave", this._hideTooltip)
|
|
87
|
-
}
|
|
88
93
|
}
|
|
89
94
|
disconnectedCallback(): void {
|
|
90
|
-
super.
|
|
91
|
-
this.target?.removeEventListener("mousemove", this._getMousePosition)
|
|
92
|
-
this.target?.removeEventListener("mouseover", this.showToolTip)
|
|
93
|
-
this.target?.removeEventListener("mouseleave", this._hideTooltip)
|
|
95
|
+
super.disconnectedCallback()
|
|
94
96
|
this.portalElement.remove()
|
|
95
97
|
}
|
|
96
98
|
private _getMousePosition = (ev: MouseEvent) => {
|
|
@@ -153,39 +155,43 @@ export class TooltipElement extends LitElement implements TooltipProps {
|
|
|
153
155
|
}
|
|
154
156
|
const bounds = this.target.getBoundingClientRect()
|
|
155
157
|
const portalBounds = this.portalElement.getBoundingClientRect()
|
|
156
|
-
if (this.target !== document.body)
|
|
158
|
+
if (this.target !== document.body) {
|
|
157
159
|
if (this.maxWidth && this.maxWidth > 0) {
|
|
158
160
|
portalBounds.width = Math.min(portalBounds.width, this.maxWidth)
|
|
159
161
|
}
|
|
162
|
+
}
|
|
163
|
+
let location: {
|
|
164
|
+
left: string;
|
|
165
|
+
top: string;
|
|
166
|
+
};
|
|
160
167
|
if (this.position === "mouse" && this.mouseLocation) {
|
|
161
168
|
this.mouseframe = undefined
|
|
162
|
-
|
|
163
|
-
this.applyStyle({ ...styles, ...location })
|
|
169
|
+
location = { left: this.mouseLocation.left + 10 + "px", top: this.mouseLocation.top - (portalBounds.height / 2) + "px" }
|
|
164
170
|
} else if (this.position === "top") {
|
|
165
|
-
|
|
171
|
+
location = {
|
|
166
172
|
top: bounds.top - portalBounds.height + "px",
|
|
167
173
|
left: (bounds.left + (bounds.width / 2)) - (portalBounds.width / 2) + "px"
|
|
168
174
|
}
|
|
169
|
-
this.applyStyle({ ...styles, ...location })
|
|
170
175
|
} else if (this.position === "bottom") {
|
|
171
|
-
|
|
176
|
+
location = {
|
|
172
177
|
top: bounds.bottom + "px",
|
|
173
178
|
left: (bounds.left + (bounds.width / 2)) - (portalBounds.width / 2) + "px"
|
|
174
179
|
}
|
|
175
|
-
this.applyStyle({ ...styles, ...location })
|
|
176
180
|
} else if (this.position === "left") {
|
|
177
|
-
|
|
181
|
+
location = {
|
|
178
182
|
top: Math.max(0, bounds.top + bounds.height / 2 - portalBounds.height / 2) + "px",
|
|
179
183
|
left: bounds.left - (portalBounds.width) + "px"
|
|
180
184
|
}
|
|
181
|
-
this.applyStyle({ ...styles, ...location })
|
|
182
185
|
} else if (this.position === "right") {
|
|
183
|
-
|
|
186
|
+
location = {
|
|
184
187
|
top: Math.max(0, bounds.top + bounds.height / 2 - portalBounds.height / 2) + "px",
|
|
185
188
|
left: bounds.right + "px"
|
|
186
189
|
}
|
|
187
|
-
|
|
190
|
+
} else {
|
|
191
|
+
location = { left: "0px", top: "0px" };
|
|
192
|
+
console.error("Unknown position... Maybe we sould implement auto?")
|
|
188
193
|
}
|
|
194
|
+
this.applyStyle({ ...styles, ...location })
|
|
189
195
|
if (this.position !== "mouse") {
|
|
190
196
|
this.portalElement.animate({ opacity: [0, 1] }, { duration: this.animationDuration })
|
|
191
197
|
}
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
Add the dist/custom-element.json to the html.languge settings
|
|
4
4
|
https://code.visualstudio.com/docs/languages/html#_html-custom-data
|
|
5
|
-

|
|
5
|
+

|
|
6
6
|
|
|
7
7
|
# VUE Integration
|
|
8
8
|
|
|
9
9
|
Complete steps to include custom elements in the HTML language server
|
|
10
10
|
then
|
|
11
11
|
Add the HTML language server in the @ext:Vue.volar extention
|
|
12
|
-

|
|
12
|
+

|
|
13
13
|
Once setup hovering over spectric elements will provide documentation
|
|
14
|
-

|
|
14
|
+

|
|
15
15
|
|
|
16
16
|
# Python Jinja
|
|
17
17
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -44,6 +44,8 @@ const meta = {
|
|
|
44
44
|
Int16-e: ${pad(dataview.getInt16(0, true))}
|
|
45
45
|
UInt16-E: ${pad(dataview.getUint16(0, false))} 0x${dataview.getUint16(0, false).toString(16)}
|
|
46
46
|
Int16-e: ${pad(dataview.getUint16(0, true))} 0x${dataview.getUint16(0, true).toString(16)}
|
|
47
|
+
F32-e: ${pad(dataview.getFloat32(0, true))}
|
|
48
|
+
F32-E: ${pad(dataview.getFloat32(0, false))}
|
|
47
49
|
</pre>`: null}
|
|
48
50
|
`},
|
|
49
51
|
|
|
@@ -56,7 +56,7 @@ export const tabledata: TestData[] = [
|
|
|
56
56
|
{ name: "Matt", company: "Spectric Labs", "contact": "912-1230", location: { "country": "UK", state: "VA" }, years: 24 },
|
|
57
57
|
{ name: "Grant", company: "Spectric Labs", "contact": "123-4567", location: { "country": "US", state: "VA" }, years: 100 },]
|
|
58
58
|
export const tablecolumns: ColumnSettings<TestData>[] = [
|
|
59
|
-
{ "title": "Company", key: "company" },
|
|
59
|
+
{ "title": "Company", key: "company", width: 200 },
|
|
60
60
|
{ "title": "Name", key: "name", sortable: true },
|
|
61
61
|
{ "title": "Contact", key: "contact" },
|
|
62
62
|
{ "title": "Country", key: "location.country", filterable: true },
|
|
@@ -5,6 +5,7 @@ import { html } from "lit";
|
|
|
5
5
|
import '../components';
|
|
6
6
|
import { ifDefined } from "lit/directives/if-defined.js";
|
|
7
7
|
import { useArgs } from "@storybook/client-api";
|
|
8
|
+
import { ButtonSizes } from "../components";
|
|
8
9
|
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
9
10
|
const meta = {
|
|
10
11
|
title: "UI/Pagination",
|
|
@@ -29,7 +30,7 @@ const meta = {
|
|
|
29
30
|
argTypes: {
|
|
30
31
|
size: {
|
|
31
32
|
control: { type: 'select' },
|
|
32
|
-
options:
|
|
33
|
+
options: Object.values(ButtonSizes),
|
|
33
34
|
},
|
|
34
35
|
},
|
|
35
36
|
args: {
|
|
@@ -8,7 +8,7 @@ import { useArgs } from "@storybook/client-api";
|
|
|
8
8
|
import { FilterEvent, rowGetValue } from "../components/table/cell";
|
|
9
9
|
import { tablecolumns, tabledata } from "./fixtures/data";
|
|
10
10
|
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
11
|
-
const data = JSON.parse(JSON.stringify(tabledata))
|
|
11
|
+
const data = JSON.parse(JSON.stringify([...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata, ...tabledata,]))
|
|
12
12
|
const columns = tablecolumns
|
|
13
13
|
const getData = TableElement.getDefaultDataSorterAndPaginatior<typeof tabledata[0]>(data)
|
|
14
14
|
const meta = {
|
|
@@ -20,12 +20,14 @@ const meta = {
|
|
|
20
20
|
|
|
21
21
|
return html`
|
|
22
22
|
<spectric-table
|
|
23
|
-
style="
|
|
23
|
+
style="height: 150px;"
|
|
24
24
|
.pagination=${args.pagination}
|
|
25
25
|
.columns=${args.columns}
|
|
26
26
|
.data=${getData(args)}
|
|
27
27
|
select=${ifDefined(args.select)}
|
|
28
28
|
sort=${ifDefined(args.sort)}
|
|
29
|
+
rowHeight=${ifDefined(args.rowHeight)}
|
|
30
|
+
@selected=${(e) => console.log(e)}
|
|
29
31
|
@filter=${(e: CustomEvent<FilterEvent<any>>) => {
|
|
30
32
|
alert(`filter ${e.detail.include ? "for" : "out"} event value ${e.detail.value}`)
|
|
31
33
|
}}
|