@spectric/ui 0.0.25 → 0.0.26

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.
@@ -1,99 +1,109 @@
1
- spectric-table{
2
- display: flex;
3
- flex-direction: column;
4
- overflow: hidden;
5
- line-height: 1;
1
+ spectric-table {
2
+ display: flex;
3
+ flex-direction: column;
4
+ overflow: hidden;
5
+ line-height: 1;
6
6
  }
7
- spectric-table .table-wrapper{
8
- overflow: auto;
9
- flex-grow: 1;
10
- position: relative;
7
+ spectric-table .table-wrapper {
8
+ overflow: auto;
9
+ flex-grow: 1;
10
+ position: relative;
11
11
  }
12
- spectric-table tr{
13
- text-align: center;
12
+ spectric-table tr {
13
+ text-align: center;
14
14
  }
15
15
 
16
- spectric-table tr.odd{
17
- background-color: color-mix(in srgb, var(--spectric-primary, #1ea7fd), transparent 90%);
18
- }
19
- spectric-table spectric-table-virtual-body tr:hover{
20
- background-color: color-mix(in srgb, var(--spectric-primary, #1ea7fd), transparent 70%)
16
+ spectric-table tr.odd {
17
+ background-color: color-mix(
18
+ in srgb,
19
+ var(--spectric-primary, #1ea7fd),
20
+ transparent 90%
21
+ );
22
+ }
23
+ spectric-table spectric-table-virtual-body tr:hover {
24
+ background-color: color-mix(
25
+ in srgb,
26
+ var(--spectric-primary, #1ea7fd),
27
+ transparent 70%
28
+ );
29
+ }
30
+ spectric-table spectric-table-virtual-body tr.virtual-scroll-spacer:hover {
31
+ background-color: unset;
21
32
  }
22
33
 
23
34
  spectric-table spectric-table-virtual-body tr {
24
- height: var(--rowHeight);
35
+ height: var(--rowHeight);
25
36
  }
26
- spectric-table td{
27
- padding:1px;
28
- border: 1px solid transparent;
37
+ spectric-table td {
38
+ padding: 1px;
39
+ border: 1px solid transparent;
29
40
  }
30
- spectric-table spectric-table-virtual-body td{
31
- height: var(--rowHeight);
41
+ spectric-table spectric-table-virtual-body td {
42
+ height: var(--rowHeight);
32
43
  }
33
44
 
34
- spectric-table div[role="table"]{
35
- display: table;
36
- min-width: 100%;
45
+ spectric-table div[role="table"] {
46
+ display: table;
47
+ min-width: 100%;
37
48
  }
38
49
 
39
- spectric-table-cell{
40
- display: contents;
41
- vertical-align: middle;
50
+ spectric-table-cell {
51
+ display: contents;
52
+ vertical-align: middle;
42
53
  }
43
- spectric-table-cell td{
44
- position: relative;
54
+ spectric-table-cell td {
55
+ position: relative;
45
56
  }
46
57
 
47
58
  spectric-table td:hover:has(.hasActions) {
48
- border: 1px solid var(--spectric-primary, #1ea7fd);
59
+ border: 1px solid var(--spectric-primary, #1ea7fd);
49
60
  }
50
61
 
51
- spectric-table-cell .table-cell-actions{
52
- position: absolute;
53
- display: flex;
54
- width: 100%;
55
- flex-direction: row-reverse;
56
- visibility: hidden;
57
- z-index: 1;
62
+ spectric-table-cell .table-cell-actions {
63
+ position: absolute;
64
+ display: flex;
65
+ width: 100%;
66
+ flex-direction: row-reverse;
67
+ visibility: hidden;
68
+ z-index: 1;
58
69
  }
59
- spectric-table-cell .table-cell-actions.tiny{
60
- top: -10px;
70
+ spectric-table-cell .table-cell-actions.tiny {
71
+ top: -10px;
61
72
  }
62
- spectric-table-cell .table-cell-actions.xxsmall{
63
- top: -16px;
73
+ spectric-table-cell .table-cell-actions.xxsmall {
74
+ top: -16px;
64
75
  }
65
- spectric-table-cell td:hover .table-cell-actions{
66
- visibility: unset;
76
+ spectric-table-cell td:hover .table-cell-actions {
77
+ visibility: unset;
67
78
  }
68
- spectric-table .table-checkbox-single spectric-button{
69
- --button-border-radius: 50%;
79
+ spectric-table .table-checkbox-single spectric-button {
80
+ --button-border-radius: 50%;
70
81
  }
71
- spectric-input.table-checkbox-single[checked] spectric-button{
72
- --text-on-color: transparent;
73
- border-radius: 50%;
74
- position: relative;
82
+ spectric-input.table-checkbox-single[checked] spectric-button {
83
+ --text-on-color: transparent;
84
+ border-radius: 50%;
85
+ position: relative;
75
86
  }
76
87
  spectric-input.table-checkbox-single[checked] spectric-button::before {
77
- position: absolute;
78
- content: " ";
79
- height: 50%;
80
- width: 50%;
81
- left: 25%;
82
- top: 25%;
83
- border-radius: 50%;
84
- z-index: 1;
85
- box-shadow: 0px 0px 0px 4px var(--input-color);
88
+ position: absolute;
89
+ content: " ";
90
+ height: 50%;
91
+ width: 50%;
92
+ left: 25%;
93
+ top: 25%;
94
+ border-radius: 50%;
95
+ z-index: 1;
96
+ box-shadow: 0px 0px 0px 4px var(--input-color);
86
97
  }
87
98
 
88
-
89
- spectric-table .cell-contents{
90
- display: -webkit-box;
91
- -webkit-box-orient: vertical;
92
- -webkit-line-clamp: var(--lineClamp,1);
93
- -webkit-box-pack: center;
94
- overflow: hidden;
95
- text-overflow: ellipsis;
96
- font-size: var(--fontSize);
97
- line-height: calc(var(--lineClamp) * var(--fontSize));
98
- height: var(--rowHeight);
99
- }
99
+ spectric-table .cell-contents {
100
+ display: -webkit-box;
101
+ -webkit-box-orient: vertical;
102
+ -webkit-line-clamp: var(--lineClamp, 1);
103
+ -webkit-box-pack: center;
104
+ overflow: hidden;
105
+ text-overflow: ellipsis;
106
+ font-size: var(--fontSize);
107
+ line-height: calc(var(--lineClamp) * var(--fontSize));
108
+ height: var(--rowHeight);
109
+ }
@@ -21,6 +21,7 @@ export type { TableProps, TableEvents };
21
21
  export type DomRenderable =
22
22
  | HTMLElement
23
23
  | TemplateResult
24
+ | TemplateResult<any>[]
24
25
  | string
25
26
  | number
26
27
  | null
@@ -72,7 +73,7 @@ export type ColumnSettings<T> = {
72
73
  render?: (
73
74
  row: T,
74
75
  index: number,
75
- table: SpectricTableElement<T>
76
+ table: SpectricTableElement<T>,
76
77
  ) => DomRenderable;
77
78
  /**
78
79
  * Custom comparator function for sorting
@@ -98,7 +99,7 @@ export type DomEvent<T> = Event & {
98
99
 
99
100
  export const TD_BorderAndPadding = 4;
100
101
  const TABLE_CREATED_SELECTION_COLUMN = Symbol(
101
- "spectric-table-selection-column"
102
+ "spectric-table-selection-column",
102
103
  );
103
104
  /**
104
105
  * React example
@@ -134,6 +135,14 @@ export class SpectricTableElement<T = any>
134
135
  @property({ type: Number, reflect: true })
135
136
  fontSize: number = 16;
136
137
 
138
+ /**
139
+ * Function that allows you to set the row class name programatically
140
+ */
141
+ @property({ type: Object, attribute: false })
142
+ getRowClass = (_row: T, index: number) => {
143
+ return index % 2 === 0 ? "odd" : "";
144
+ };
145
+
137
146
  protected cellActionButtonSize: ButtonSizesTypes = "xxsmall";
138
147
  getCellActionButtonSize() {
139
148
  return this.cellActionButtonSize;
@@ -143,7 +152,7 @@ export class SpectricTableElement<T = any>
143
152
  //let sorts = props.columns.filter(column => column.sortable && column.sortDirection && column.sortDirection !== TableSortDirection.none)
144
153
  let sorts = (props.sortOrder || []).map(
145
154
  (key) =>
146
- props.columns.find((col) => col.key === key) as ColumnSettings<T>
155
+ props.columns.find((col) => col.key === key) as ColumnSettings<T>,
147
156
  );
148
157
  let rows = [...data]; // Need to copy the array to prevent mutating the ordering of the original data
149
158
  if (sorts.length) {
@@ -190,7 +199,7 @@ export class SpectricTableElement<T = any>
190
199
  this.dispatchEvent(
191
200
  new CustomEvent<PaginationChangeProps>("paginationChange", {
192
201
  detail: e.detail,
193
- })
202
+ }),
194
203
  );
195
204
  this._emitChange();
196
205
  };
@@ -236,7 +245,7 @@ export class SpectricTableElement<T = any>
236
245
  this.dispatchEvent(
237
246
  new CustomEvent<TableDataOptions<T>>("change", {
238
247
  detail: { pagination, columns, sortOrder },
239
- })
248
+ }),
240
249
  );
241
250
  };
242
251
  //@ts-ignore
@@ -254,7 +263,7 @@ export class SpectricTableElement<T = any>
254
263
  // Because lit reuses dom elements for speed/effeciency it wont update unless the props are a different object.
255
264
  // So we set the selection colum to a "new object" to force the rerender
256
265
  let index = this.columns.findIndex(
257
- (col) => col[TABLE_CREATED_SELECTION_COLUMN]
266
+ (col) => col[TABLE_CREATED_SELECTION_COLUMN],
258
267
  );
259
268
  if (index !== -1) {
260
269
  this.columns[index] = { ...this.selectColumnConfig };
@@ -293,7 +302,7 @@ export class SpectricTableElement<T = any>
293
302
  });
294
303
  //Wait for the smooth scroll to complete. Scroll to doesn't return a promise so we must manually check periodically
295
304
  for (let wait = 0; wait < 100; wait++) {
296
- await new Promise((resolve) => setTimeout(resolve, 10));
305
+ await new Promise((resolve) => requestAnimationFrame(resolve));
297
306
  if (wrapper.scrollTop == scrollPosition) {
298
307
  console.log("Scroll complete");
299
308
  break;
@@ -304,12 +313,12 @@ export class SpectricTableElement<T = any>
304
313
  requestAnimationFrame(() => {
305
314
  let rows = [...body.querySelectorAll("tr")];
306
315
  rows = rows.filter(
307
- (row) => row.querySelector("spectric-table-cell")?.index === index
316
+ (row) => row.querySelector("spectric-table-cell")?.index === index,
308
317
  );
309
318
  if (rows.length) {
310
319
  rows[0].animate(
311
320
  [{ backgroundColor: "red" }, { backgroundColor: "unset" }],
312
- { duration: 200, iterations: 5 }
321
+ { duration: 200, iterations: 5 },
313
322
  );
314
323
  }
315
324
  });
@@ -373,7 +382,7 @@ export class SpectricTableElement<T = any>
373
382
  }
374
383
  table.setSelected([...table.selected]);
375
384
  table.dispatchEvent(
376
- new CustomEvent("selected", { detail: [...table.selected] })
385
+ new CustomEvent("selected", { detail: [...table.selected] }),
377
386
  );
378
387
  }}
379
388
  ></spectric-input>`;
@@ -398,7 +407,7 @@ export class SpectricTableElement<T = any>
398
407
  }
399
408
  if (changedProperties.has("select")) {
400
409
  let selectIndex = this.columns.findIndex(
401
- (col) => col[TABLE_CREATED_SELECTION_COLUMN]
410
+ (col) => col[TABLE_CREATED_SELECTION_COLUMN],
402
411
  );
403
412
  if (this.select !== TableSelectOptions.none) {
404
413
  this.forceRefreshofSelectionColumn();
@@ -419,7 +428,7 @@ export class SpectricTableElement<T = any>
419
428
  ) {
420
429
  this.setSelected([this.selected[0]]);
421
430
  this.dispatchEvent(
422
- new CustomEvent("selected", { detail: [this.selected[0]] })
431
+ new CustomEvent("selected", { detail: [this.selected[0]] }),
423
432
  );
424
433
  }
425
434
  }
@@ -1,4 +1,4 @@
1
- import { html } from "lit";
1
+ import { html, PropertyValues } from "lit";
2
2
  import { customElement, property } from "lit/decorators.js";
3
3
  import {
4
4
  HTMLElementTagWithEvents,
@@ -56,10 +56,10 @@ export class TableVirtualBodyElement<T>
56
56
  }
57
57
  lastScroll = scrollTop;
58
58
  this.startIndex = Math.floor(scrollTop / this.rowHeight);
59
- }
59
+ },
60
60
  );
61
61
  }
62
- protected updated(): void {
62
+ protected update(changedProperties: PropertyValues): void {
63
63
  if (this.columnsMeasured === false) {
64
64
  let tr = this.querySelector("tr");
65
65
  let cells = tr?.querySelectorAll("spectric-table-cell td");
@@ -78,7 +78,9 @@ export class TableVirtualBodyElement<T>
78
78
  }
79
79
  }
80
80
  }
81
+ super.update(changedProperties);
81
82
  }
83
+
82
84
  protected createRenderRoot(): HTMLElement | DocumentFragment {
83
85
  return this;
84
86
  }
@@ -86,12 +88,12 @@ export class TableVirtualBodyElement<T>
86
88
  let totalRows = this.data.length;
87
89
  let buffer = 10; // Have a buffer of rows to prevent column jitter
88
90
  let headerHeight = this.table.querySelector(
89
- "spectric-table-header"
91
+ "spectric-table-header",
90
92
  )!.clientHeight;
91
93
  let viewport = this.table.querySelector(".table-wrapper")!;
92
94
  let startIndex = Math.max(this.startIndex, 0);
93
95
  const rowsThatFit = Math.ceil(
94
- (viewport.clientHeight - headerHeight) / this.rowHeight
96
+ (viewport.clientHeight - headerHeight) / this.rowHeight,
95
97
  );
96
98
  const endIndex = Math.min(startIndex + rowsThatFit + buffer, totalRows);
97
99
  const visibleRows = endIndex - startIndex;
@@ -132,19 +134,20 @@ export class TableVirtualBodyElement<T>
132
134
  >
133
135
  ${repeat(
134
136
  this.data.slice(Math.max(startIndex, 0), endIndex),
135
- (row, index) => html` <tr
136
- class="${(index + startIndex) % 2 === 0 ? "odd" : ""}"
137
- >
138
- ${repeat(this.columns, (col) => {
139
- return html`<spectric-table-cell
140
- .column=${col}
141
- .row=${row}
142
- .index=${index + startIndex}
143
- .columns=${this.columns}
144
- .table=${this.table}
145
- ></spectric-table-cell>`;
146
- })}
147
- </tr>`
137
+ (row, index) =>
138
+ html` <tr
139
+ class="${this.table.getRowClass(row, index + startIndex)}"
140
+ >
141
+ ${repeat(this.columns, (col) => {
142
+ return html`<spectric-table-cell
143
+ .column=${col}
144
+ .row=${row}
145
+ .index=${index + startIndex}
146
+ .columns=${this.columns}
147
+ .table=${this.table}
148
+ ></spectric-table-cell>`;
149
+ })}
150
+ </tr>`,
148
151
  )}
149
152
  </div>
150
153
  <tbody>
@@ -9,17 +9,18 @@ import { html } from "lit";
9
9
  import { ifDefined } from "lit/directives/if-defined.js";
10
10
  import { useArgs } from "@storybook/client-api";
11
11
  import { filterByColumn } from "./fixtures/data";
12
+ import { createRef, ref } from "lit/directives/ref.js";
12
13
  // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
13
- var code = "";
14
14
 
15
15
  const meta = {
16
16
  title: "UI/Query",
17
17
  tags: ["autodocs"],
18
18
  component: "spectric-query",
19
19
  render: (args) => {
20
+ const code = createRef<HTMLPreElement>();
20
21
  const [_, updateArgs] = useArgs();
21
22
  const fakevalues = async (field, text) => {
22
- if (!args.fields.find((f) => f.name === field)) {
23
+ if (!args.fields || !args.fields.find((f) => f.name === field)) {
23
24
  return [];
24
25
  }
25
26
  return filterByColumn(field, text);
@@ -30,16 +31,15 @@ const meta = {
30
31
  .getValuesForField=${fakevalues}
31
32
  value=${ifDefined(args.value)}
32
33
  @change=${(e: CustomEvent<any>) => {
33
- code = e.detail;
34
+ if (code.value) {
35
+ code.value.innerText = JSON.stringify(e.detail, null, 2);
36
+ }
34
37
  updateArgs({ ...args });
35
38
  }}
36
- outputLanguage=${args.outputLanguage}
39
+ .outputLanguage=${args.outputLanguage}
37
40
  >
38
41
  </spectric-query>
39
- <pre>
40
- ${JSON.stringify(code, null, 2)}
41
- </pre
42
- >
42
+ <pre ${ref(code)}></pre>
43
43
  `;
44
44
  },
45
45
  argTypes: {
@@ -50,6 +50,7 @@ const meta = {
50
50
  },
51
51
  args: {
52
52
  outputLanguage: "toDSL",
53
+ value: "",
53
54
  fields: [
54
55
  { name: "test", type: "string" },
55
56
  { name: "test_num", type: "number" },
@@ -136,6 +136,7 @@ export type TestData = {
136
136
  state: string;
137
137
  };
138
138
  years: number;
139
+ start: string;
139
140
  };
140
141
  export const tabledata: TestData[] = [
141
142
  {
@@ -144,6 +145,7 @@ export const tabledata: TestData[] = [
144
145
  contact: "123-4567",
145
146
  location: { country: "US", state: "VA" },
146
147
  years: 11,
148
+ start: "2025-12-19T20:22:42.008Z",
147
149
  },
148
150
  {
149
151
  name: "Kipp",
@@ -151,6 +153,7 @@ export const tabledata: TestData[] = [
151
153
  contact: "123-4567",
152
154
  location: { country: "UK", state: "N/A" },
153
155
  years: 5,
156
+ start: "2024-12-19T20:22:42.008Z",
154
157
  },
155
158
  {
156
159
  name: "Adam",
@@ -158,6 +161,7 @@ export const tabledata: TestData[] = [
158
161
  contact: "123-4567",
159
162
  location: { country: "US", state: "VA" },
160
163
  years: 19,
164
+ start: "2023-12-19T20:22:42.008Z",
161
165
  },
162
166
  {
163
167
  name: "Chris",
@@ -165,6 +169,7 @@ export const tabledata: TestData[] = [
165
169
  contact: "123-4567",
166
170
  location: { country: "US", state: "VA" },
167
171
  years: 27,
172
+ start: "2022-12-19T20:22:42.008Z",
168
173
  },
169
174
  {
170
175
  name: "Michael",
@@ -172,6 +177,7 @@ export const tabledata: TestData[] = [
172
177
  contact: "123-4567",
173
178
  location: { country: "US", state: "VA" },
174
179
  years: 3,
180
+ start: "2021-12-19T20:22:42.008Z",
175
181
  },
176
182
  {
177
183
  name: "Matt",
@@ -179,6 +185,7 @@ export const tabledata: TestData[] = [
179
185
  contact: "123-4567",
180
186
  location: { country: "US", state: "VA" },
181
187
  years: 9,
188
+ start: "2021-12-19T20:22:42.008Z",
182
189
  },
183
190
  {
184
191
  name: "Matt",
@@ -186,6 +193,7 @@ export const tabledata: TestData[] = [
186
193
  contact: "865-6343",
187
194
  location: { country: "UK", state: "VA" },
188
195
  years: 5,
196
+ start: "2025-11-19T20:22:42.008Z",
189
197
  },
190
198
  {
191
199
  name: "Matt",
@@ -193,6 +201,7 @@ export const tabledata: TestData[] = [
193
201
  contact: "253-6795",
194
202
  location: { country: "UK", state: "VA" },
195
203
  years: 15,
204
+ start: "2025-10-19T20:22:42.008Z",
196
205
  },
197
206
  {
198
207
  name: "Matt",
@@ -200,6 +209,7 @@ export const tabledata: TestData[] = [
200
209
  contact: "253-6795",
201
210
  location: { country: "US", state: "CO" },
202
211
  years: 1,
212
+ start: "2025-08-19T20:22:42.008Z",
203
213
  },
204
214
  {
205
215
  name: "Matt",
@@ -207,6 +217,7 @@ export const tabledata: TestData[] = [
207
217
  contact: "912-1230",
208
218
  location: { country: "UK", state: "VA" },
209
219
  years: 24,
220
+ start: "2025-07-19T20:22:42.008Z",
210
221
  },
211
222
  {
212
223
  name: "Grant",
@@ -214,6 +225,7 @@ export const tabledata: TestData[] = [
214
225
  contact: "123-4567",
215
226
  location: { country: "US", state: "VA" },
216
227
  years: 100,
228
+ start: "2022-01-19T20:22:42.008Z",
217
229
  },
218
230
  ];
219
231
  export const getTableColumns = () => {
@@ -229,28 +241,13 @@ export const getTableColumns = () => {
229
241
  onClick: (row, _column) => {
230
242
  alert(`Calling ${row.name} at ${row.contact}`);
231
243
  },
232
- icon: html`<svg
233
- width="16px"
234
- height="16px"
235
- viewBox="0 0 24 24"
236
- fill="none"
237
- xmlns="http://www.w3.org/2000/svg"
238
- >
239
- <g>
240
- <path
241
- d="M14.05 6C15.0268 6.19057 15.9244 6.66826 16.6281 7.37194C17.3318 8.07561 17.8095 8.97326 18 9.95M14.05 2C16.0793 2.22544 17.9716 3.13417 19.4163 4.57701C20.8609 6.01984 21.7721 7.91101 22 9.94M18.5 21C9.93959 21 3 14.0604 3 5.5C3 5.11378 3.01413 4.73086 3.04189 4.35173C3.07375 3.91662 3.08968 3.69907 3.2037 3.50103C3.29814 3.33701 3.4655 3.18146 3.63598 3.09925C3.84181 3 4.08188 3 4.56201 3H7.37932C7.78308 3 7.98496 3 8.15802 3.06645C8.31089 3.12515 8.44701 3.22049 8.55442 3.3441C8.67601 3.48403 8.745 3.67376 8.88299 4.05321L10.0491 7.26005C10.2096 7.70153 10.2899 7.92227 10.2763 8.1317C10.2643 8.31637 10.2012 8.49408 10.0942 8.64506C9.97286 8.81628 9.77145 8.93713 9.36863 9.17882L8 10C9.2019 12.6489 11.3501 14.7999 14 16L14.8212 14.6314C15.0629 14.2285 15.1837 14.0271 15.3549 13.9058C15.5059 13.7988 15.6836 13.7357 15.8683 13.7237C16.0777 13.7101 16.2985 13.7904 16.74 13.9509L19.9468 15.117C20.3262 15.255 20.516 15.324 20.6559 15.4456C20.7795 15.553 20.8749 15.6891 20.9335 15.842C21 16.015 21 16.2169 21 16.6207V19.438C21 19.9181 21 20.1582 20.9007 20.364C20.8185 20.5345 20.663 20.7019 20.499 20.7963C20.3009 20.9103 20.0834 20.9262 19.6483 20.9581C19.2691 20.9859 18.8862 21 18.5 21Z"
242
- stroke="#000000"
243
- stroke-width="2"
244
- stroke-linecap="round"
245
- stroke-linejoin="round"
246
- ></path>
247
- </g>
248
- </svg>`,
244
+ icon: "☎",
249
245
  },
250
246
  ],
251
247
  },
252
248
  { title: "Country", key: "location.country", filterable: true },
253
249
  { title: "Years Employed", key: "years", sortable: true },
250
+ { title: "Start Date", key: "start", sortable: true },
254
251
  ];
255
252
  return tablecolumns;
256
253
  };