@spectric/ui 0.0.16 → 0.0.17
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/dist/classes/DisposibleElement.d.ts +1 -0
- package/dist/classes/index.d.ts +2 -0
- package/dist/components/color_picker/ColorPicker.d.ts +59 -0
- package/dist/components/color_picker/index.d.ts +0 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/input.d.ts +3 -1
- package/dist/components/table/body.d.ts +2 -2
- package/dist/components/table/cell.d.ts +2 -2
- package/dist/components/table/header.d.ts +9 -3
- package/dist/components/table/table.d.ts +18 -6
- package/dist/components/table/virtualBody.d.ts +2 -2
- package/dist/components/tooltip/popover.d.ts +85 -0
- package/dist/components/tooltip/tooltip.d.ts +14 -15
- package/dist/custom-elements.json +83 -8
- package/dist/index.d.ts +58 -0
- package/dist/index.es.js +2635 -2249
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +183 -132
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/utils/index.d.ts +3 -0
- package/package.json +6 -2
- package/src/classes/DisposibleElement.ts +3 -0
- package/src/classes/index.ts +2 -0
- package/src/components/color_picker/ColorPicker.css +4 -0
- package/src/components/color_picker/ColorPicker.ts +244 -0
- package/src/components/color_picker/index.ts +1 -0
- package/src/components/index.ts +3 -1
- package/src/components/input.css +38 -1
- package/src/components/input.ts +34 -7
- package/src/components/table/__tests__/table.spec.ts +91 -0
- package/src/components/table/body.ts +2 -2
- package/src/components/table/cell.ts +11 -5
- package/src/components/table/header.css +54 -0
- package/src/components/table/header.ts +144 -49
- package/src/components/table/table.css +11 -34
- package/src/components/table/table.ts +50 -16
- package/src/components/table/virtualBody.ts +2 -2
- package/src/components/tooltip/popover.ts +221 -0
- package/src/components/tooltip/tooltip.css +21 -16
- package/src/components/tooltip/tooltip.ts +17 -124
- package/src/index.ts +8 -1
- package/src/stories/fixtures/ExampleContent.ts +3 -3
- package/src/stories/table.stories.ts +5 -5
- package/src/utils/index.ts +3 -0
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
|
|
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.hue-gradient input[type=range]::-webkit-slider-runnable-track{background:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.saturation-lightness-grid{background:linear-gradient(to right,hsl(var(--accent-color),0%,50%),hsl(var(--accent-color),100%,50%)),linear-gradient(to top,hsl(var(--accent-color),100%,0%),hsl(var(--accent-color),100%,50%),hsl(var(--accent-color),100%,100%))}spectric-input.alpha-gradient input[type=range]::-webkit-slider-runnable-track{background-image:linear-gradient(to right,#fff0,#fff)}spectric-input.alpha-gradient input[type=range],spectric-input.hue-gradient input[type=range]{-webkit-appearance:none;-moz-appearance:none;appearance:none}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 #helper-text.hidden{display:none}spectric-input[variant=password] spectric-button{position:absolute;right:4px;bottom:3px}spectric-input .checkbox{display:flex;justify-self:center}spectric-input spectric-colorpicker{display:block}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;line-height:1}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 spectric-table-virtual-body tr:hover{background-color:color-mix(in srgb,var(--spectric-primary, #1ea7fd),transparent 70%)}spectric-table tr{height:var(--rowHeight)}spectric-table td{height:var(--rowHeight);padding:1px;border:1px solid transparent}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-cell .table-cell-actions{position:absolute;display:flex;width:100%;flex-direction:row-reverse;visibility:hidden;top:-10px;z-index:1}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 .cell-contents{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--lineClamp,1);-webkit-box-pack:center;overflow:hidden;text-overflow:ellipsis;font-size:var(--fontSize);height:calc(var(--lineClamp) * var(--fontSize))}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;position:relative}spectric-table-header .header-contents{position:relative}spectric-table-header .header-contents .sort-direction{position:absolute;right:2px;top:calc(50% - 8px)}spectric-table-header .header-contents.sortable{cursor:pointer;padding-right:15px}spectric-table-header .header-contents.resizing{-webkit-user-select:none;user-select:none}spectric-table-header .header-contents.sortable:hover .sort-direction.none:before{content:"⮁"}spectric-table-header td .header-resize-handle{width:2px;position:absolute;right:-1px;top:1px;visibility:hidden;background-color:var(--spectric-primary, #1ea7fd);height:100%;cursor:ew-resize;z-index:1}spectric-table-header td:hover .header-resize-handle{visibility:visible}spectric-table-header td:hover:has(*.header-resize-handle){border-bottom:1px solid var(--spectric-primary, #1ea7fd)}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-popover-portal{position:fixed;z-index:9999;--spectric-tooltip-background-color: var(--spectric-tooltip-background, #000000);--spectric-tooltip-text-color: var(--spectric-tooltip-text, var(--spectric-text-primary, white));--spectric-tooltip-accent-color: var(--spectric-tooltip-accent, var(--spectric-primary, #1ea7fd))}.spectric-popover-portal.spectric-tooltip-portal{pointer-events:none}.spectric-popover-portal .tooltip-container{display:flex;justify-content:center;align-items:center}.spectric-popover-portal.top .tooltip-container{flex-direction:column-reverse}.spectric-popover-portal.bottom .tooltip-container{flex-direction:column}.spectric-popover-portal.left .tooltip-container{flex-direction:row-reverse}.spectric-popover-portal .tooltip-content{background:var(--spectric-tooltip-background-color);border-radius:var(--spectric-border-radius,.4em);border:1px solid color-mix(in srgb,var(--spectric-tooltip-background-color) 90%,var(--spectric-tooltip-accent-color) 90%);box-shadow:0 0 .01em .01em color-mix(in srgb,var(--spectric-tooltip-accent-color) 90%,var(--spectric-text-on-color,#ffffff) 90%);padding:.2em;color:var(--spectric-tooltip-text-color)}.spectric-popover-portal .tooltip-caret{background:color-mix(in srgb,var(--spectric-tooltip-background-color) 90%,var(--spectric-tooltip-accent-color) 90%)}.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-popover-portal.top .tooltip-caret{clip-path:polygon(0 0,50% 100%,100% 0)}.spectric-popover-portal.bottom .tooltip-caret{clip-path:polygon(0 100%,50% 0,100% 100%)}.spectric-popover-portal.left .tooltip-caret{clip-path:polygon(0 0,100% 50%,0 100%)}.spectric-popover-portal.right .tooltip-caret{clip-path:polygon(0 50%,100% 0,100% 100%)}.color-picker-footer{display:flex;justify-content:space-evenly}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spectric/ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.es.js",
|
|
6
6
|
"module": "./dist/index.es.js",
|
|
@@ -13,14 +13,18 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsc && vite build",
|
|
15
15
|
"start": "storybook dev -p 6006",
|
|
16
|
+
"test-setup": "storybook dev -p 6006 --no-open --ci --loglevel verbose",
|
|
16
17
|
"storybook:build": "web-component-analyzer src --outFiles .storybook/build/custom-elements.json && storybook build --output-dir public",
|
|
17
|
-
"release": "npm version patch && git push --follow-tags"
|
|
18
|
+
"release": "npm version patch && git push --follow-tags",
|
|
19
|
+
"test": "playwright test --reporter=list --timeout 90000",
|
|
20
|
+
"type-check": "tsc --noemit"
|
|
18
21
|
},
|
|
19
22
|
"dependencies": {
|
|
20
23
|
"lit": "^3.2.1"
|
|
21
24
|
},
|
|
22
25
|
"devDependencies": {
|
|
23
26
|
"@chromatic-com/storybook": "^3.2.2",
|
|
27
|
+
"@playwright/test": "^1.55.0",
|
|
24
28
|
"@storybook/addon-essentials": "^8.4.6",
|
|
25
29
|
"@storybook/blocks": "^8.4.6",
|
|
26
30
|
"@storybook/client-api": "^7.6.17",
|
|
@@ -5,6 +5,9 @@ export interface IDisposable {
|
|
|
5
5
|
}
|
|
6
6
|
type DisposableTarget = HTMLElement | Promise<HTMLElement> | (() => HTMLElement)
|
|
7
7
|
let listeners = 0;
|
|
8
|
+
export const getListeners = () => {
|
|
9
|
+
return listeners
|
|
10
|
+
}
|
|
8
11
|
class DomListener implements IDisposable {
|
|
9
12
|
|
|
10
13
|
private _handler?: (e: any) => void;
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { html, LitElement, PropertyValues, TemplateResult } from 'lit';
|
|
2
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
|
3
|
+
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from '../types';
|
|
4
|
+
import { PopoverElement } from '../tooltip/popover';
|
|
5
|
+
import { createRef, ref } from 'lit/directives/ref.js';
|
|
6
|
+
import { DomEvent, } from '../table';
|
|
7
|
+
import { SpectricInput } from '../input';
|
|
8
|
+
import "./ColorPicker.css"
|
|
9
|
+
export interface ColorPickerProps {
|
|
10
|
+
/**Color in hex*/
|
|
11
|
+
value?: string,
|
|
12
|
+
showAlpha?: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@customElement('spectric-colorpicker')
|
|
16
|
+
export class SpectricColorPicker extends LitElement implements ColorPickerProps {
|
|
17
|
+
@property({ type: String, reflect: true })
|
|
18
|
+
value = "#FF0000FF"
|
|
19
|
+
@property({ type: Boolean, reflect: true })
|
|
20
|
+
showAlpha = true
|
|
21
|
+
@state()
|
|
22
|
+
private hue: number = 0;
|
|
23
|
+
@state()
|
|
24
|
+
private alpha: number = 1;
|
|
25
|
+
@state()
|
|
26
|
+
private saturation: number = 1;
|
|
27
|
+
@state()
|
|
28
|
+
private lightness: number = 1;
|
|
29
|
+
private canvas = createRef<HTMLCanvasElement>()
|
|
30
|
+
private original?: string;
|
|
31
|
+
/**is mouse down on saturation/light canvas? */
|
|
32
|
+
private sldown: boolean = false;
|
|
33
|
+
|
|
34
|
+
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
35
|
+
return this
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
protected update(changedProperties: PropertyValues): void {
|
|
39
|
+
if (changedProperties.has("value")) {
|
|
40
|
+
let { h, s, l, a } = hexToHsl(this.value)
|
|
41
|
+
this.hue = h
|
|
42
|
+
this.saturation = s;
|
|
43
|
+
this.lightness = l;
|
|
44
|
+
this.alpha = a
|
|
45
|
+
this.renderHueSaturationGrid()
|
|
46
|
+
}
|
|
47
|
+
super.update(changedProperties)
|
|
48
|
+
}
|
|
49
|
+
private renderHueSaturationGrid() {
|
|
50
|
+
console.log("canvas render")
|
|
51
|
+
if (!this.canvas.value) {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
let canvas: HTMLCanvasElement = this.canvas.value;
|
|
55
|
+
let ctx = canvas.getContext("2d");
|
|
56
|
+
if (!ctx) {
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
let xpix = this.canvas.value.width / 100
|
|
60
|
+
let ypix = this.canvas.value.height / 100
|
|
61
|
+
let x = 0,
|
|
62
|
+
y = 0; //pixel size
|
|
63
|
+
for (let m of hslGen(this.hue)) {
|
|
64
|
+
ctx.fillStyle = m;
|
|
65
|
+
ctx.fillRect(x, y, xpix, ypix); //Need to made this a 2d saturation, light graph
|
|
66
|
+
x += xpix;
|
|
67
|
+
x = x % (xpix * 101);
|
|
68
|
+
if (!x)
|
|
69
|
+
y += ypix;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
_handleSaturationLightnessClick = (e: PointerEvent) => {
|
|
73
|
+
if (!this.canvas.value) {
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
let { offsetX, offsetY } = e
|
|
77
|
+
this.saturation = offsetX / this.canvas.value.width
|
|
78
|
+
this.lightness = (this.canvas.value.height - offsetY) / this.canvas.value.height
|
|
79
|
+
this.updateValue()
|
|
80
|
+
}
|
|
81
|
+
_handleHueChange = (e: DomEvent<SpectricInput>) => {
|
|
82
|
+
this.hue = (parseInt(String(e.target.value)) / 100) * 360
|
|
83
|
+
e.target.style.setProperty("accent-color", `hsl(${this.hue}deg 100% 50%)`)
|
|
84
|
+
this.renderHueSaturationGrid()
|
|
85
|
+
this.updateValue()
|
|
86
|
+
}
|
|
87
|
+
private updateValue() {
|
|
88
|
+
this.value = hslToHex(this.hue, this.saturation * 100, this.lightness * 100) + (Math.round(this.alpha * 255).toString(16).padStart(2, "0"))
|
|
89
|
+
}
|
|
90
|
+
_handleAlphaChange = (e: DomEvent<SpectricInput>) => {
|
|
91
|
+
this.alpha = parseInt(String(e.target.value)) / 100
|
|
92
|
+
console.log(this.alpha, e)
|
|
93
|
+
this.updateValue()
|
|
94
|
+
}
|
|
95
|
+
_handleApply = () => {
|
|
96
|
+
console.log(this.hue, this.saturation, this.lightness, this.alpha)
|
|
97
|
+
this.updateValue()
|
|
98
|
+
console.log(this.value)
|
|
99
|
+
this.querySelector<PopoverElement>("spectric-popover")?.hidePopover()
|
|
100
|
+
}
|
|
101
|
+
_cancel = () => {
|
|
102
|
+
if (this.original) {
|
|
103
|
+
this.value = this.original
|
|
104
|
+
}
|
|
105
|
+
this.querySelector<PopoverElement>("spectric-popover")?.hidePopover()
|
|
106
|
+
}
|
|
107
|
+
_openPopover = async () => {
|
|
108
|
+
this.original = this.value
|
|
109
|
+
this.querySelector<PopoverElement>("spectric-popover")?.showPopover()
|
|
110
|
+
while (!this.canvas.value) {
|
|
111
|
+
await new Promise(resolve => setTimeout(resolve, 100))
|
|
112
|
+
}
|
|
113
|
+
this.renderHueSaturationGrid()
|
|
114
|
+
}
|
|
115
|
+
protected getPopover(): TemplateResult {
|
|
116
|
+
return html`
|
|
117
|
+
<spectric-input label="Hue" class="hue-gradient" variant="range" .value=${this.hue || 0} style="accent-color:hsl(${this.hue}deg 100% 50%)" @change=${this._handleHueChange}></spectric-input>
|
|
118
|
+
<canvas ${ref(this.canvas)} width=200 height=100 class="saturation-lightness-grid" @click=${this._handleSaturationLightnessClick}
|
|
119
|
+
@mousedown=${() => { this.sldown = true }}
|
|
120
|
+
@mouseup=${() => this.sldown = false}
|
|
121
|
+
@mousemove=${(e: PointerEvent) => { if (this.sldown) { this._handleSaturationLightnessClick(e) } }}
|
|
122
|
+
></canvas>
|
|
123
|
+
<spectric-input class="alpha-gradient" ?hidden=${!this.showAlpha} label="Opacity" variant="range" .value=${(this.alpha || 1) * 100} @change=${this._handleAlphaChange}></spectric-input>
|
|
124
|
+
<div class="color-picker-footer">
|
|
125
|
+
<spectric-button @click=${this._handleApply}>Apply</spectric-button>
|
|
126
|
+
<spectric-button variant="secondary" @click=${this._cancel}>Cancel</spectric-button>
|
|
127
|
+
</div>
|
|
128
|
+
`
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
protected render(): unknown {
|
|
132
|
+
return html`
|
|
133
|
+
<spectric-button variant="text" @click=${this._openPopover}>
|
|
134
|
+
<spectric-popover .text=${this.getPopover()} icon variant="text"></spectric-popover>
|
|
135
|
+
<div style="width:15px;height:15px;background-color:${this.value}"></div>
|
|
136
|
+
</spectric-button>
|
|
137
|
+
`;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function* hslGen(hue: number) {
|
|
142
|
+
for (let l = 100; l >= 0; l--) {
|
|
143
|
+
for (let s = 0; s <= 100; s++) {
|
|
144
|
+
yield `hsl(${hue}, ${s}%, ${l}%)`;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function hslToHex(h: number, s: number, l: number) {
|
|
149
|
+
l /= 100;
|
|
150
|
+
const a = s * Math.min(l, 1 - l) / 100;
|
|
151
|
+
const f = (n: number) => {
|
|
152
|
+
const k = (n + h / 30) % 12;
|
|
153
|
+
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
154
|
+
return Math.round(255 * color).toString(16).padStart(2, '0'); // convert to Hex and prefix "0" if needed
|
|
155
|
+
};
|
|
156
|
+
return `#${f(0)}${f(8)}${f(4)}`;
|
|
157
|
+
}
|
|
158
|
+
function hexToHsl(hex: string) {
|
|
159
|
+
// Convert hex to RGB
|
|
160
|
+
let r = 0, g = 0, b = 0, a = 255;
|
|
161
|
+
if (hex.length === 4 || hex.length === 5) { // Handle shorthand hex codes like #F0C
|
|
162
|
+
r = parseInt(hex[1] + hex[1], 16);
|
|
163
|
+
g = parseInt(hex[2] + hex[2], 16);
|
|
164
|
+
b = parseInt(hex[3] + hex[3], 16);
|
|
165
|
+
if (hex.length === 5) {
|
|
166
|
+
a = parseInt(hex[4] + hex[4], 16);
|
|
167
|
+
}
|
|
168
|
+
} else if (hex.length === 7 || hex.length === 9) { // Handle full hex codes like #FF00CC
|
|
169
|
+
r = parseInt(hex.substring(1, 3), 16);
|
|
170
|
+
g = parseInt(hex.substring(3, 5), 16);
|
|
171
|
+
b = parseInt(hex.substring(5, 7), 16);
|
|
172
|
+
if (hex.length === 9) {
|
|
173
|
+
a = parseInt(hex.substring(7, 9), 16);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Normalize RGB values to a range of 0-1
|
|
178
|
+
r /= 255;
|
|
179
|
+
g /= 255;
|
|
180
|
+
b /= 255;
|
|
181
|
+
a /= 255
|
|
182
|
+
// Find min and max values among R, G, B
|
|
183
|
+
const max = Math.max(r, g, b);
|
|
184
|
+
const min = Math.min(r, g, b);
|
|
185
|
+
|
|
186
|
+
let h = 0, s = 0, l = (max + min) / 2;
|
|
187
|
+
|
|
188
|
+
if (max === min) {
|
|
189
|
+
// Achromatic (grayscale)
|
|
190
|
+
h = 0;
|
|
191
|
+
s = 0;
|
|
192
|
+
} else {
|
|
193
|
+
const d = max - min;
|
|
194
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
195
|
+
|
|
196
|
+
switch (max) {
|
|
197
|
+
case r:
|
|
198
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
199
|
+
break;
|
|
200
|
+
case g:
|
|
201
|
+
h = (b - r) / d + 2;
|
|
202
|
+
break;
|
|
203
|
+
case b:
|
|
204
|
+
h = (r - g) / d + 4;
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
h /= 6;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Convert Hue to degrees
|
|
211
|
+
h = Math.round(h * 360);
|
|
212
|
+
|
|
213
|
+
//leave sla as 0-1
|
|
214
|
+
return { h, s, l, a };
|
|
215
|
+
}
|
|
216
|
+
export interface ColorPickerEventMap {
|
|
217
|
+
'change': (event: CustomEvent<ColorPickerProps>) => void
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
declare global {
|
|
221
|
+
|
|
222
|
+
interface HTMLElementTagNameMap {
|
|
223
|
+
"spectric-colorpicker": HTMLElementTagWithEvents<SpectricColorPicker, ColorPickerEventMap>
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
namespace JSX {
|
|
227
|
+
interface IntrinsicElements {
|
|
228
|
+
/**
|
|
229
|
+
* {@link SpectricColorPicker}
|
|
230
|
+
*/
|
|
231
|
+
"spectric-colorpicker": ReactElementWithPropsAndEvents<SpectricColorPicker, ColorPickerProps, ColorPickerEventMap>;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
namespace React {
|
|
235
|
+
namespace JSX {
|
|
236
|
+
interface IntrinsicElements {
|
|
237
|
+
/**
|
|
238
|
+
* {@link SpectricColorPicker}
|
|
239
|
+
*/
|
|
240
|
+
"spectric-colorpicker": ReactElementWithPropsAndEvents<SpectricColorPicker, ColorPickerProps, ColorPickerEventMap>;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./ColorPicker"
|
package/src/components/index.ts
CHANGED
package/src/components/input.css
CHANGED
|
@@ -14,7 +14,39 @@ spectric-input {
|
|
|
14
14
|
spectric-input .inputWrapper {
|
|
15
15
|
color: var(--text-secondary)
|
|
16
16
|
}
|
|
17
|
+
spectric-input.hue-gradient input[type="range"]::-webkit-slider-runnable-track {
|
|
18
|
+
background: linear-gradient(
|
|
19
|
+
to right,
|
|
20
|
+
hsl(0, 100%, 50%), /* Red */
|
|
21
|
+
hsl(60, 100%, 50%), /* Yellow */
|
|
22
|
+
hsl(120, 100%, 50%), /* Green */
|
|
23
|
+
hsl(180, 100%, 50%), /* Cyan */
|
|
24
|
+
hsl(240, 100%, 50%), /* Blue */
|
|
25
|
+
hsl(300, 100%, 50%), /* Magenta */
|
|
26
|
+
hsl(360, 100%, 50%) /* Red (completes the circle) */
|
|
27
|
+
)
|
|
28
|
+
}
|
|
17
29
|
|
|
30
|
+
.saturation-lightness-grid {
|
|
31
|
+
/* Assuming a fixed hue, e.g., 240 (blue) */
|
|
32
|
+
background: linear-gradient(to right,
|
|
33
|
+
hsl(var(--accent-color), 0%, 50%), /* From desaturated */
|
|
34
|
+
hsl(var(--accent-color), 100%, 50%) /* To fully saturated */
|
|
35
|
+
),
|
|
36
|
+
linear-gradient(to top,
|
|
37
|
+
hsl(var(--accent-color), 100%, 0%), /* From dark */
|
|
38
|
+
hsl(var(--accent-color), 100%, 50%), /* To mid-lightness */
|
|
39
|
+
hsl(var(--accent-color), 100%, 100%) /* To bright */
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
spectric-input.alpha-gradient input[type="range"]::-webkit-slider-runnable-track {
|
|
43
|
+
background-image:
|
|
44
|
+
/* Alpha gradient from transparent to opaque */
|
|
45
|
+
linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
|
|
46
|
+
}
|
|
47
|
+
spectric-input.alpha-gradient input[type="range"],spectric-input.hue-gradient input[type="range"]{ -webkit-appearance: none; /* For WebKit browsers (Chrome, Safari) */
|
|
48
|
+
-moz-appearance: none; /* For Mozilla Firefox */
|
|
49
|
+
appearance: none; /* Standard property */}
|
|
18
50
|
spectric-input .inputWrapper input {
|
|
19
51
|
box-sizing: border-box;
|
|
20
52
|
margin: 0px;
|
|
@@ -67,7 +99,9 @@ spectric-input .inputContainer::after {
|
|
|
67
99
|
spectric-input #helper-text {
|
|
68
100
|
height: 18px;
|
|
69
101
|
}
|
|
70
|
-
|
|
102
|
+
spectric-input #helper-text.hidden {
|
|
103
|
+
display: none;
|
|
104
|
+
}
|
|
71
105
|
spectric-input[variant="password"] spectric-button {
|
|
72
106
|
position: absolute;
|
|
73
107
|
right: 4px;
|
|
@@ -77,4 +111,7 @@ spectric-input[variant="password"] spectric-button {
|
|
|
77
111
|
spectric-input .checkbox{
|
|
78
112
|
display: flex;
|
|
79
113
|
justify-self: center;
|
|
114
|
+
}
|
|
115
|
+
spectric-input spectric-colorpicker{
|
|
116
|
+
display: block;
|
|
80
117
|
}
|
package/src/components/input.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { html, LitElement, PropertyValues, TemplateResult } from 'lit';
|
|
2
2
|
import "./input.css"
|
|
3
|
-
import { customElement, property, query } from 'lit/decorators.js';
|
|
3
|
+
import { customElement, eventOptions, property, query } from 'lit/decorators.js';
|
|
4
4
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
5
5
|
import { ReactElementWithPropsAndEvents } from './types';
|
|
6
6
|
import { ButtonSizesTypes } from './Button';
|
|
7
|
+
import { DomEvent } from './table';
|
|
8
|
+
import { SpectricColorPicker } from './color_picker/ColorPicker';
|
|
7
9
|
|
|
8
10
|
export enum InputVariants {
|
|
9
11
|
Text = 'text',
|
|
@@ -17,7 +19,8 @@ export enum InputVariants {
|
|
|
17
19
|
file = "file",//display drop area
|
|
18
20
|
hidden = "hidden",//display drop area
|
|
19
21
|
password = "password",
|
|
20
|
-
checkbox = "checkbox"
|
|
22
|
+
checkbox = "checkbox",
|
|
23
|
+
range = "range"
|
|
21
24
|
|
|
22
25
|
}
|
|
23
26
|
type InputVariantsTypes = `${InputVariants}`
|
|
@@ -232,6 +235,11 @@ export class SpectricInput extends LitElement implements InputProps {
|
|
|
232
235
|
this.dispatchEvent(new Event("change", { bubbles: true }))
|
|
233
236
|
}
|
|
234
237
|
}
|
|
238
|
+
@eventOptions({ capture: true })
|
|
239
|
+
_handleChange(e: Event) {
|
|
240
|
+
e.stopPropagation()
|
|
241
|
+
this.dispatchEvent(new Event("change", { bubbles: true }))
|
|
242
|
+
}
|
|
235
243
|
protected render(): unknown {
|
|
236
244
|
switch (this.variant) {
|
|
237
245
|
case InputVariants.Text:
|
|
@@ -243,7 +251,7 @@ export class SpectricInput extends LitElement implements InputProps {
|
|
|
243
251
|
case InputVariants.date://replace with custom date picker
|
|
244
252
|
case InputVariants.datetime://replace with custom date picker
|
|
245
253
|
case InputVariants.file://replace with drag and drop location and custom select file button
|
|
246
|
-
case InputVariants.
|
|
254
|
+
case InputVariants.range:
|
|
247
255
|
return html`
|
|
248
256
|
<div class="inputWrapper">
|
|
249
257
|
<div class="text-input__label-helper-wrapper">
|
|
@@ -271,9 +279,7 @@ export class SpectricInput extends LitElement implements InputProps {
|
|
|
271
279
|
.value="${this._value as string}"
|
|
272
280
|
maxlength="${ifNonEmpty(this.maxCount > 0 ? this.maxCount : undefined)}"
|
|
273
281
|
@input="${this._handleInput}"
|
|
274
|
-
@change=${
|
|
275
|
-
this.dispatchEvent(new Event("change", { bubbles: true }))
|
|
276
|
-
}}
|
|
282
|
+
@change=${this._handleChange}
|
|
277
283
|
/>
|
|
278
284
|
|
|
279
285
|
${this.variant === String(InputVariants.password) && this.showPasswordVisibilityToggle
|
|
@@ -290,6 +296,7 @@ export class SpectricInput extends LitElement implements InputProps {
|
|
|
290
296
|
</div>
|
|
291
297
|
<div
|
|
292
298
|
id="helper-text"
|
|
299
|
+
class="${this.helperText || this.invalid ? "" : "hidden"}"
|
|
293
300
|
>
|
|
294
301
|
<slot name="helper-text"> ${this.invalid ? this.invalidText : this.helperText} </slot>
|
|
295
302
|
</div>
|
|
@@ -298,8 +305,28 @@ export class SpectricInput extends LitElement implements InputProps {
|
|
|
298
305
|
</div>
|
|
299
306
|
`;
|
|
300
307
|
|
|
308
|
+
case InputVariants.color: //replace with custom color picker
|
|
309
|
+
return html`<div class="inputWrapper">
|
|
310
|
+
<div class="text-input__label-helper-wrapper">
|
|
311
|
+
<div class="--text-input__label-wrapper">
|
|
312
|
+
${this.label} ${this.maxCount > 0 && this._value ? `${(this._value as String).length}/${this.maxCount}` : null}
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
<div class="fieldwrapper">
|
|
316
|
+
<div ?data-invalid="${this.invalid}" class="inputContainer">
|
|
317
|
+
<spectric-colorpicker @change=${(e: DomEvent<SpectricColorPicker>) => { this.value = e.target.value; this._handleChange(e) }}></spectric-colorpicker>
|
|
318
|
+
</div>
|
|
319
|
+
<div
|
|
320
|
+
id="helper-text"
|
|
321
|
+
class="${this.helperText || this.invalid ? "" : "hidden"}"
|
|
322
|
+
>
|
|
323
|
+
<slot name="helper-text"> ${this.invalid ? this.invalidText : this.helperText} </slot>
|
|
324
|
+
</div>
|
|
325
|
+
|
|
326
|
+
</div>
|
|
327
|
+
</div>`
|
|
301
328
|
case InputVariants.hidden:
|
|
302
|
-
return html`<input type="hidden"
|
|
329
|
+
return html`<input type="hidden"/>`
|
|
303
330
|
|
|
304
331
|
case InputVariants.checkbox:
|
|
305
332
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
import type { SpectricTableElement, TableEvents } from '../index';
|
|
3
|
+
import type SpectricModule from "../../../index.ts"
|
|
4
|
+
test.beforeEach(async ({ page }) => {
|
|
5
|
+
await page.addInitScript(() => {
|
|
6
|
+
//@ts-ignore
|
|
7
|
+
window.awaitEvent = function awaitEvent(target, event, trigger) {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
const handleEvent = (...args) => {
|
|
10
|
+
//@ts-ignore
|
|
11
|
+
target.removeEventListener(event, this)
|
|
12
|
+
resolve(args)
|
|
13
|
+
}
|
|
14
|
+
//@ts-ignore
|
|
15
|
+
target.addEventListener(event, handleEvent)
|
|
16
|
+
trigger()
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
await page.goto('http://localhost:6006/iframe.html?globals=&args=&id=spectric-ui-components-ui-table--milti-select&viewMode=story');
|
|
21
|
+
});
|
|
22
|
+
test.describe("Spectric Table Tests", () => {
|
|
23
|
+
|
|
24
|
+
test('MultiSelect Table Select All/Deselect All ', async ({ page }) => {
|
|
25
|
+
let tableLocator = page.locator("spectric-table")
|
|
26
|
+
tableLocator.waitFor()
|
|
27
|
+
var selected = await tableLocator.evaluate<number, SpectricTableElement>(
|
|
28
|
+
async (table) => {
|
|
29
|
+
console.log("here")
|
|
30
|
+
let selectAll = table.querySelectorAll<HTMLElement>("spectric-table-header spectric-input[variant='checkbox'] spectric-button")[0]
|
|
31
|
+
let [event] = await window.awaitEvent<TableEvents>(table, "selected", () => selectAll.click()) as Parameters<TableEvents["selected"]>
|
|
32
|
+
return event.detail.length
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
await expect(selected, "All Selected").toBeGreaterThan(0)
|
|
36
|
+
|
|
37
|
+
selected = await tableLocator.evaluate<number, SpectricTableElement>(
|
|
38
|
+
async (table) => {
|
|
39
|
+
let selectAll = table.querySelectorAll<HTMLElement>("spectric-table-header spectric-input[variant='checkbox'] spectric-button")[0]
|
|
40
|
+
let [event] = await window.awaitEvent<TableEvents>(table, "selected", () => selectAll.click()) as Parameters<TableEvents["selected"]>
|
|
41
|
+
return event.detail.length
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
await expect(selected, "None Selected").toBe(0)
|
|
45
|
+
|
|
46
|
+
selected = await tableLocator.evaluate<number, SpectricTableElement>(
|
|
47
|
+
async (table) => {
|
|
48
|
+
let selectAll = table.querySelectorAll<HTMLElement>("spectric-table-virtual-body spectric-input[variant='checkbox'] spectric-button")[2]
|
|
49
|
+
let [event] = await window.awaitEvent<TableEvents>(table, "selected", () => selectAll.click()) as Parameters<TableEvents["selected"]>
|
|
50
|
+
return event.detail.length
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
await expect(selected, "One Selected").toBe(1)
|
|
54
|
+
|
|
55
|
+
selected = await tableLocator.evaluate<number, SpectricTableElement>(
|
|
56
|
+
async (table) => {
|
|
57
|
+
let selectAll = table.querySelectorAll<HTMLElement>("spectric-table-virtual-body spectric-input[variant='checkbox'] spectric-button")[2]
|
|
58
|
+
let [event] = await window.awaitEvent<TableEvents>(table, "selected", () => selectAll.click()) as Parameters<TableEvents["selected"]>
|
|
59
|
+
return event.detail.length
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
await expect(selected, "One DeSelected").toBe(0)
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
test('Ensure all event listeners are cleaned up and not leaked', async ({ page }) => {
|
|
67
|
+
let tableLocator = page.locator("spectric-table")
|
|
68
|
+
await tableLocator.waitFor()
|
|
69
|
+
let listenerCount = await page.evaluate(async () => {
|
|
70
|
+
const module = await import("./src/index.ts") as typeof SpectricModule
|
|
71
|
+
return module.getListeners()
|
|
72
|
+
})
|
|
73
|
+
await expect(listenerCount).toBeGreaterThan(0)
|
|
74
|
+
//Delete all content and expect everything to get cleaned up
|
|
75
|
+
listenerCount = await page.evaluate(async () => {
|
|
76
|
+
const module = await import("./src/index.ts") as typeof SpectricModule
|
|
77
|
+
document.body.innerHTML = ""
|
|
78
|
+
return module.getListeners()
|
|
79
|
+
})
|
|
80
|
+
await expect(listenerCount).toBe(0)
|
|
81
|
+
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
declare global {
|
|
88
|
+
interface Window {
|
|
89
|
+
awaitEvent: <EventMap extends Record<string, any>, K = keyof EventMap>(target: HTMLElement, event: K, trigger: () => void) => Parameters<EventMap[keyof EventMap]>;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -3,7 +3,7 @@ import { customElement, property, } from 'lit/decorators.js';
|
|
|
3
3
|
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from '../types';
|
|
4
4
|
export const TableBodyElementTag = "spectric-table-body"
|
|
5
5
|
import "./cell"
|
|
6
|
-
import { ColumnSettings,
|
|
6
|
+
import { ColumnSettings, SpectricTableElement } from './table';
|
|
7
7
|
import { repeat } from 'lit/directives/repeat.js';
|
|
8
8
|
|
|
9
9
|
interface BodyProps<T> {
|
|
@@ -21,7 +21,7 @@ export class TableBodyElement<T> extends LitElement implements BodyProps<T> {
|
|
|
21
21
|
data: T[] = [];
|
|
22
22
|
@property({ type: Array, attribute: false })
|
|
23
23
|
columns: ColumnSettings<T>[] = [];
|
|
24
|
-
table!:
|
|
24
|
+
table!: SpectricTableElement<T>
|
|
25
25
|
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
26
26
|
return this
|
|
27
27
|
}
|
|
@@ -2,7 +2,7 @@ import { html, LitElement, PropertyValues } from 'lit';
|
|
|
2
2
|
import { customElement, property, query, state, } from 'lit/decorators.js';
|
|
3
3
|
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from '../types';
|
|
4
4
|
export const TableCellElementTag = "spectric-table-cell"
|
|
5
|
-
import { ColumnSettings, DomRenderable,
|
|
5
|
+
import { ColumnSettings, DomRenderable, SpectricTableElement } from './table';
|
|
6
6
|
import { cache } from 'lit/directives/cache.js';
|
|
7
7
|
import { StyleInfo, styleMap } from 'lit/directives/style-map.js';
|
|
8
8
|
|
|
@@ -31,7 +31,7 @@ export class TableCellElement<T> extends LitElement implements CellProps<T> {
|
|
|
31
31
|
@property({ type: Object, attribute: false })
|
|
32
32
|
column!: ColumnSettings<T>;
|
|
33
33
|
columns!: ColumnSettings<T>[];
|
|
34
|
-
table!:
|
|
34
|
+
table!: SpectricTableElement<T>
|
|
35
35
|
|
|
36
36
|
@state()
|
|
37
37
|
overflow: DomRenderable = ""
|
|
@@ -77,7 +77,7 @@ export class TableCellElement<T> extends LitElement implements CellProps<T> {
|
|
|
77
77
|
})
|
|
78
78
|
}
|
|
79
79
|
_displayTooltip = () => {
|
|
80
|
-
let div = this.querySelector("div")
|
|
80
|
+
let div = this.querySelector("div.cell-contents")
|
|
81
81
|
let span = this.querySelector("span")
|
|
82
82
|
if (div && span) {
|
|
83
83
|
let spanBounds = span.getBoundingClientRect()
|
|
@@ -85,6 +85,12 @@ export class TableCellElement<T> extends LitElement implements CellProps<T> {
|
|
|
85
85
|
if ((spanBounds.width * spanBounds.height) > (divBounds.width * divBounds.height)) {
|
|
86
86
|
console.log("We need to show a tooltip witht he content because we are overflowing")
|
|
87
87
|
this.overflow = this.getRenderedValue()
|
|
88
|
+
this.updateComplete.then(() => {
|
|
89
|
+
let tooltip = this.querySelector("spectric-tooltip")
|
|
90
|
+
if (tooltip) {
|
|
91
|
+
tooltip.showToolTip()
|
|
92
|
+
}
|
|
93
|
+
})
|
|
88
94
|
} else {
|
|
89
95
|
this.overflow = ""
|
|
90
96
|
}
|
|
@@ -115,8 +121,8 @@ export class TableCellElement<T> extends LitElement implements CellProps<T> {
|
|
|
115
121
|
: null
|
|
116
122
|
)
|
|
117
123
|
this.styleRules = {
|
|
118
|
-
width: this.column.width ? this.column.width + "px" :
|
|
119
|
-
whiteSpace: this.column.whiteSpace ||
|
|
124
|
+
width: this.column.width ? this.column.width + "px" : null,
|
|
125
|
+
whiteSpace: this.column.whiteSpace || null
|
|
120
126
|
}
|
|
121
127
|
return html`
|
|
122
128
|
<td style=${styleMap(this.styleRules)} @mouseenter=${this._displayTooltip}>
|