@spectric/ui 0.0.15 → 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 +5 -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 +2640 -2243
- 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 +34 -8
- package/src/components/table/header.css +54 -0
- package/src/components/table/header.ts +144 -49
- package/src/components/table/table.css +20 -33
- 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
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
|
|
2
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
+
import "./tooltip.css"
|
|
4
|
+
export const PopoverElementTag = "spectric-popover"
|
|
5
|
+
import { css, CSSResultGroup, html, render } from "lit-element";
|
|
6
|
+
import { DomRenderable } from "../table";
|
|
7
|
+
import { DisposableElement } from '../../classes/DisposibleElement';
|
|
8
|
+
export type { TooltipProps, TooltipEvents }
|
|
9
|
+
export enum TooltipPostions {
|
|
10
|
+
top = "top",
|
|
11
|
+
bottom = "bottom",
|
|
12
|
+
left = "left",
|
|
13
|
+
right = "right",
|
|
14
|
+
mouse = "mouse"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type TooltipPostionsTypes = `${TooltipPostions}`
|
|
18
|
+
interface TooltipProps {
|
|
19
|
+
/**
|
|
20
|
+
* How long you need to hover before the tooltip displays
|
|
21
|
+
*/
|
|
22
|
+
delay?: number;
|
|
23
|
+
/**
|
|
24
|
+
* How long the fade in animation should run
|
|
25
|
+
*/
|
|
26
|
+
animationDuration?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Tooltip contents
|
|
29
|
+
*/
|
|
30
|
+
text: DomRenderable
|
|
31
|
+
/**
|
|
32
|
+
* Where to anchor the tooltip
|
|
33
|
+
*/
|
|
34
|
+
position?: TooltipPostionsTypes
|
|
35
|
+
/**
|
|
36
|
+
* Sets a max width for the contents you can disable this by setting to 0 or -1
|
|
37
|
+
*/
|
|
38
|
+
maxWidth?: number
|
|
39
|
+
/**
|
|
40
|
+
* Container the tool tip will be attached to.
|
|
41
|
+
*/
|
|
42
|
+
portalTarget?: HTMLElement
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 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
|
+
triggerTarget?: HTMLElement
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Spectric tooltip will add a tooltip to any container
|
|
52
|
+
*/
|
|
53
|
+
@customElement(PopoverElementTag)
|
|
54
|
+
export class PopoverElement extends DisposableElement implements TooltipProps {
|
|
55
|
+
@property({ type: Number, reflect: true })
|
|
56
|
+
delay: number = 100;
|
|
57
|
+
@property({ type: Number, reflect: true })
|
|
58
|
+
animationDuration: number = 0;
|
|
59
|
+
@property({ type: String, reflect: false })
|
|
60
|
+
text: DomRenderable = "";
|
|
61
|
+
@property({ type: String, reflect: true })
|
|
62
|
+
position: TooltipPostionsTypes = "right";
|
|
63
|
+
@property({ type: Number, reflect: true })
|
|
64
|
+
maxWidth?: number = 300;
|
|
65
|
+
protected portalElement!: HTMLDivElement
|
|
66
|
+
protected mouseLocation?: { left: number; top: number; };
|
|
67
|
+
static styles?: CSSResultGroup | undefined = css`:host{max-height: 0px;
|
|
68
|
+
max-width: 0px;
|
|
69
|
+
display: none;
|
|
70
|
+
pointer-events:none;}`;
|
|
71
|
+
@property({ attribute: false })
|
|
72
|
+
portalTarget: HTMLElement = document.body
|
|
73
|
+
protected timer?: number;
|
|
74
|
+
protected open: boolean = false;
|
|
75
|
+
protected mouseframe?: number;
|
|
76
|
+
/**
|
|
77
|
+
* @default parentElement
|
|
78
|
+
*/
|
|
79
|
+
@property({ attribute: false })
|
|
80
|
+
triggerTarget!: HTMLElement;
|
|
81
|
+
protected get target() {
|
|
82
|
+
return this.triggerTarget || this.parentElement
|
|
83
|
+
}
|
|
84
|
+
constructor() {
|
|
85
|
+
super()
|
|
86
|
+
/**
|
|
87
|
+
* Public method to trigger showing the tooltip programatically
|
|
88
|
+
*/
|
|
89
|
+
this.showPopover = this.showPopover.bind(this)
|
|
90
|
+
this.hidePopover = this.hidePopover.bind(this)
|
|
91
|
+
this.addDisposableListener(() => this.target, "mousemove", this._getMousePosition)
|
|
92
|
+
}
|
|
93
|
+
connectedCallback(): void {
|
|
94
|
+
super.connectedCallback()
|
|
95
|
+
this.portalElement = document.createElement("div")
|
|
96
|
+
this.portalElement.className = "spectric-tooltip-portal"
|
|
97
|
+
console.log("connected")
|
|
98
|
+
}
|
|
99
|
+
disconnectedCallback(): void {
|
|
100
|
+
super.disconnectedCallback();
|
|
101
|
+
this.portalElement.remove()
|
|
102
|
+
//@ts-ignore
|
|
103
|
+
this.portalElement = undefined
|
|
104
|
+
}
|
|
105
|
+
protected _getMousePosition = (ev: MouseEvent) => {
|
|
106
|
+
this.mouseLocation = {
|
|
107
|
+
left: ev.clientX,
|
|
108
|
+
top: ev.clientY
|
|
109
|
+
}
|
|
110
|
+
if (this.position == "mouse" && this.open && !this.mouseframe) {
|
|
111
|
+
this.mouseframe = requestAnimationFrame(() => this.positionTooltip())
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Public method to trigger hide the tooltip programatically
|
|
116
|
+
*/
|
|
117
|
+
public hidePopover() {
|
|
118
|
+
if (this.timer) {
|
|
119
|
+
clearTimeout(this.timer)
|
|
120
|
+
}
|
|
121
|
+
this.open = false
|
|
122
|
+
this.portalElement.remove()
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Public method to trigger showing the tooltip programatically
|
|
126
|
+
*/
|
|
127
|
+
public async showPopover() {
|
|
128
|
+
if (this.timer) {
|
|
129
|
+
clearTimeout(this.timer)
|
|
130
|
+
}
|
|
131
|
+
await new Promise(resolve => {
|
|
132
|
+
this.timer = window.setTimeout(resolve, this.delay)
|
|
133
|
+
})
|
|
134
|
+
this.portalElement.className = `spectric-popover-portal ${this.position}`
|
|
135
|
+
const tooltip = html`<div class="tooltip-container">
|
|
136
|
+
<span class="tooltip-caret"></span>
|
|
137
|
+
<div class="tooltip-content">${this.text}</div>
|
|
138
|
+
</div>`
|
|
139
|
+
render(tooltip, this.portalElement)
|
|
140
|
+
//with the delay it is possible that the triggering element was removed or hidden lets check that it is visible
|
|
141
|
+
if (!this.target || !this.target.checkVisibility()) {
|
|
142
|
+
return
|
|
143
|
+
}
|
|
144
|
+
//We need to append our tooltip and let the css updates apply before we can take measurements
|
|
145
|
+
this.portalTarget.appendChild(this.portalElement)
|
|
146
|
+
this.open = true
|
|
147
|
+
requestAnimationFrame(this.positionTooltip)
|
|
148
|
+
}
|
|
149
|
+
protected applyStyle = (style: Record<string, string>) => {
|
|
150
|
+
Object.entries(style).forEach(([prop, value]) => {
|
|
151
|
+
this.portalElement.style.setProperty(prop, value)
|
|
152
|
+
})
|
|
153
|
+
}
|
|
154
|
+
protected positionTooltip = () => {
|
|
155
|
+
if (!this.target) {
|
|
156
|
+
//We got detached before the animation frame completed
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
//Since we are attaching to a body we need to send the correct styles from the target portion of the dom to the portal element
|
|
160
|
+
let computedStyle = getComputedStyle(this)
|
|
161
|
+
let styles = {
|
|
162
|
+
"--spectric-primary": computedStyle.getPropertyValue("--spectric-primary"),
|
|
163
|
+
"--spectric-background-inverse": computedStyle.getPropertyValue("--spectric-background-inverse"),
|
|
164
|
+
"--spectric-background-hover": computedStyle.getPropertyValue("--spectric-background-hover"),
|
|
165
|
+
"--spectric-text-on-color": computedStyle.getPropertyValue("--spectric-text-on-color"),
|
|
166
|
+
"--spectric-border-radius": computedStyle.getPropertyValue("--spectric-border-radius"),
|
|
167
|
+
}
|
|
168
|
+
const bounds = this.target.getBoundingClientRect()
|
|
169
|
+
const portalBounds = this.portalElement.getBoundingClientRect()
|
|
170
|
+
if (this.target !== document.body) {
|
|
171
|
+
if (this.maxWidth && this.maxWidth > 0) {
|
|
172
|
+
portalBounds.width = Math.min(portalBounds.width, this.maxWidth)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
let location: {
|
|
176
|
+
left: string;
|
|
177
|
+
top: string;
|
|
178
|
+
};
|
|
179
|
+
if (this.position === "mouse" && this.mouseLocation) {
|
|
180
|
+
this.mouseframe = undefined
|
|
181
|
+
location = { left: this.mouseLocation.left + 10 + "px", top: this.mouseLocation.top - (portalBounds.height / 2) + "px" }
|
|
182
|
+
} else if (this.position === "top") {
|
|
183
|
+
location = {
|
|
184
|
+
top: bounds.top - portalBounds.height + "px",
|
|
185
|
+
left: (bounds.left + (bounds.width / 2)) - (portalBounds.width / 2) + "px"
|
|
186
|
+
}
|
|
187
|
+
} else if (this.position === "bottom") {
|
|
188
|
+
location = {
|
|
189
|
+
top: bounds.bottom + "px",
|
|
190
|
+
left: (bounds.left + (bounds.width / 2)) - (portalBounds.width / 2) + "px"
|
|
191
|
+
}
|
|
192
|
+
} else if (this.position === "left") {
|
|
193
|
+
location = {
|
|
194
|
+
top: Math.max(0, bounds.top + bounds.height / 2 - portalBounds.height / 2) + "px",
|
|
195
|
+
left: bounds.left - (portalBounds.width) + "px"
|
|
196
|
+
}
|
|
197
|
+
} else if (this.position === "right") {
|
|
198
|
+
location = {
|
|
199
|
+
top: Math.max(0, bounds.top + bounds.height / 2 - portalBounds.height / 2) + "px",
|
|
200
|
+
left: bounds.right + "px"
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
location = { left: "0px", top: "0px" };
|
|
204
|
+
console.error("Unknown position... Maybe we sould implement auto?")
|
|
205
|
+
}
|
|
206
|
+
this.applyStyle({ ...styles, ...location })
|
|
207
|
+
if (this.position !== "mouse") {
|
|
208
|
+
this.portalElement.animate({ opacity: [0, 1] }, { duration: this.animationDuration })
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
protected render() {
|
|
212
|
+
//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.
|
|
213
|
+
// See showTooltip for the real rendering
|
|
214
|
+
return html`<!-- ToolTip -->`
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
interface TooltipEvents {
|
|
219
|
+
//'open': (event: CustomEvent<{ pagination: PaginationChangeProps }>) => void;
|
|
220
|
+
//'filter': (event: CustomEvent<FilterEvent>) => void;
|
|
221
|
+
}
|
|
@@ -1,34 +1,39 @@
|
|
|
1
|
-
.spectric-
|
|
1
|
+
.spectric-popover-portal{
|
|
2
2
|
position: fixed;
|
|
3
3
|
z-index: 9999;
|
|
4
|
+
--spectric-tooltip-background-color: var(--spectric-tooltip-background, #000000);
|
|
5
|
+
--spectric-tooltip-text-color: var(--spectric-tooltip-text, var(--spectric-text-primary, white));
|
|
6
|
+
--spectric-tooltip-accent-color: var(--spectric-tooltip-accent, var(--spectric-primary, #1ea7fd));
|
|
7
|
+
}
|
|
8
|
+
.spectric-popover-portal.spectric-tooltip-portal{
|
|
4
9
|
pointer-events: none;
|
|
5
|
-
--spectric-tooltip-background: color-mix(in srgb,var(--spectric-background-inverse,#f4f4f4) 100%,var(--spectric-primary,#1ea7fd) 90%)
|
|
6
10
|
}
|
|
7
|
-
.spectric-
|
|
11
|
+
.spectric-popover-portal .tooltip-container{
|
|
8
12
|
display: flex;
|
|
9
13
|
justify-content: center;
|
|
10
14
|
align-items: center;
|
|
11
15
|
}
|
|
12
|
-
.spectric-
|
|
16
|
+
.spectric-popover-portal.top .tooltip-container{
|
|
13
17
|
flex-direction: column-reverse;
|
|
14
18
|
}
|
|
15
|
-
.spectric-
|
|
19
|
+
.spectric-popover-portal.bottom .tooltip-container{
|
|
16
20
|
flex-direction: column;
|
|
17
21
|
}
|
|
18
|
-
.spectric-
|
|
22
|
+
.spectric-popover-portal.left .tooltip-container{
|
|
19
23
|
flex-direction: row-reverse;
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
.spectric-
|
|
23
|
-
background: var(--spectric-tooltip-background);
|
|
26
|
+
.spectric-popover-portal .tooltip-content{
|
|
27
|
+
background: var(--spectric-tooltip-background-color);
|
|
24
28
|
border-radius: var(--spectric-border-radius,.4em);
|
|
25
|
-
|
|
29
|
+
border: 1px solid color-mix(in srgb, var(--spectric-tooltip-background-color) 90%, var(--spectric-tooltip-accent-color) 90%);
|
|
30
|
+
box-shadow: 0 0 .01em .01em color-mix(in srgb, var(--spectric-tooltip-accent-color) 90%, var(--spectric-text-on-color,#ffffff) 90%);
|
|
26
31
|
padding: .2em;
|
|
27
|
-
color:var(--spectric-text-
|
|
32
|
+
color:var(--spectric-tooltip-text-color);
|
|
28
33
|
}
|
|
29
34
|
|
|
30
|
-
.spectric-
|
|
31
|
-
background:var(--spectric-tooltip-background);
|
|
35
|
+
.spectric-popover-portal .tooltip-caret{
|
|
36
|
+
background:color-mix(in srgb, var(--spectric-tooltip-background-color) 90%, var(--spectric-tooltip-accent-color) 90%);
|
|
32
37
|
}
|
|
33
38
|
.spectric-tooltip-portal.top .tooltip-caret,.spectric-tooltip-portal.bottom .tooltip-caret{
|
|
34
39
|
inline-size: .75rem;
|
|
@@ -38,15 +43,15 @@
|
|
|
38
43
|
inline-size: .375rem;
|
|
39
44
|
block-size: .75rem;
|
|
40
45
|
}
|
|
41
|
-
.spectric-
|
|
46
|
+
.spectric-popover-portal.top .tooltip-caret{
|
|
42
47
|
clip-path: polygon(0 0,50% 100%,100% 0);
|
|
43
48
|
}
|
|
44
|
-
.spectric-
|
|
49
|
+
.spectric-popover-portal.bottom .tooltip-caret{
|
|
45
50
|
clip-path: polygon(0 100%,50% 0,100% 100%);
|
|
46
51
|
}
|
|
47
|
-
.spectric-
|
|
52
|
+
.spectric-popover-portal.left .tooltip-caret{
|
|
48
53
|
clip-path: polygon(0 0,100% 50%,0 100%);
|
|
49
54
|
}
|
|
50
|
-
.spectric-
|
|
55
|
+
.spectric-popover-portal.right .tooltip-caret{
|
|
51
56
|
clip-path: polygon(0 50% ,100% 0, 100% 100%);
|
|
52
57
|
}
|
|
@@ -3,9 +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 } from "lit-element";
|
|
7
7
|
import { DomRenderable } from "../table";
|
|
8
|
-
import {
|
|
8
|
+
import { PopoverElement } from './popover';
|
|
9
9
|
export type { TooltipProps, TooltipEvents }
|
|
10
10
|
export enum TooltipPostions {
|
|
11
11
|
top = "top",
|
|
@@ -52,7 +52,7 @@ interface TooltipProps {
|
|
|
52
52
|
* Spectric tooltip will add a tooltip to any container
|
|
53
53
|
*/
|
|
54
54
|
@customElement(TooltipElementTag)
|
|
55
|
-
export class TooltipElement extends
|
|
55
|
+
export class TooltipElement extends PopoverElement implements TooltipProps {
|
|
56
56
|
@property({ type: Number, reflect: true })
|
|
57
57
|
delay: number = 100;
|
|
58
58
|
@property({ type: Number, reflect: true })
|
|
@@ -63,143 +63,36 @@ 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
|
-
|
|
67
|
-
|
|
66
|
+
portalElement!: HTMLDivElement
|
|
67
|
+
mouseLocation?: { left: number; top: number; };
|
|
68
68
|
static styles?: CSSResultGroup | undefined = css`:host{max-height: 0px;
|
|
69
69
|
max-width: 0px;
|
|
70
70
|
display: none;
|
|
71
71
|
pointer-events:none;}`;
|
|
72
72
|
@property({ attribute: false })
|
|
73
73
|
portalTarget: HTMLElement = document.body
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
timer?: number;
|
|
75
|
+
open: boolean = false;
|
|
76
|
+
mouseframe?: number;
|
|
77
77
|
/**
|
|
78
78
|
* @default parentElement
|
|
79
79
|
*/
|
|
80
80
|
@property({ attribute: false })
|
|
81
81
|
triggerTarget!: HTMLElement;
|
|
82
|
-
private get target() {
|
|
83
|
-
return this.triggerTarget || this.parentElement
|
|
84
|
-
}
|
|
85
82
|
constructor() {
|
|
86
83
|
super()
|
|
87
|
-
this.addDisposableListener(() => this.target, "mousemove", this._getMousePosition)
|
|
88
84
|
this.addDisposableListener(() => this.target, "mouseover", this.showToolTip)
|
|
89
|
-
this.addDisposableListener(() => this.target, "mouseleave", this.
|
|
90
|
-
}
|
|
91
|
-
connectedCallback(): void {
|
|
92
|
-
super.connectedCallback()
|
|
93
|
-
this.portalElement = document.createElement("div")
|
|
94
|
-
this.portalElement.className = "spectric-tooltip-portal"
|
|
85
|
+
this.addDisposableListener(() => this.target, "mouseleave", this.hidePopover)
|
|
95
86
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
this.mouseLocation = {
|
|
104
|
-
left: ev.clientX,
|
|
105
|
-
top: ev.clientY
|
|
106
|
-
}
|
|
107
|
-
if (this.position == "mouse" && this.open && !this.mouseframe) {
|
|
108
|
-
this.mouseframe = requestAnimationFrame(() => this.positionTooltip())
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
_hideTooltip = () => {
|
|
112
|
-
if (this.timer) {
|
|
113
|
-
clearTimeout(this.timer)
|
|
114
|
-
}
|
|
115
|
-
this.open = false
|
|
116
|
-
this.portalElement.remove()
|
|
117
|
-
}
|
|
118
|
-
private showToolTip = async () => {
|
|
119
|
-
if (this.timer) {
|
|
120
|
-
clearTimeout(this.timer)
|
|
121
|
-
}
|
|
122
|
-
await new Promise(resolve => {
|
|
123
|
-
this.timer = window.setTimeout(resolve, this.delay)
|
|
124
|
-
})
|
|
125
|
-
this.portalElement.style.pointerEvents = "none"
|
|
126
|
-
this.portalElement.className = `spectric-tooltip-portal ${this.position}`
|
|
127
|
-
const tooltip = html`<div class="tooltip-container">
|
|
128
|
-
<span class="tooltip-caret"></span>
|
|
129
|
-
<div class="tooltip-content">${this.text}</div>
|
|
130
|
-
</div>`
|
|
131
|
-
render(tooltip, this.portalElement)
|
|
132
|
-
//with the delay it is possible that the triggering element was removed or hidden lets check that it is visible
|
|
133
|
-
if (!this.target || !this.target.checkVisibility()) {
|
|
134
|
-
return
|
|
135
|
-
}
|
|
136
|
-
//We need to append our tooltip and let the css updates apply before we can take measurements
|
|
137
|
-
this.portalTarget.appendChild(this.portalElement)
|
|
138
|
-
this.open = true
|
|
139
|
-
requestAnimationFrame(this.positionTooltip)
|
|
140
|
-
}
|
|
141
|
-
private applyStyle = (style: Record<string, string>) => {
|
|
142
|
-
Object.entries(style).forEach(([prop, value]) => {
|
|
143
|
-
this.portalElement.style.setProperty(prop, value)
|
|
144
|
-
})
|
|
145
|
-
}
|
|
146
|
-
private positionTooltip = () => {
|
|
147
|
-
if (!this.target) {
|
|
148
|
-
//We got detached before the animation frame completed
|
|
149
|
-
return
|
|
150
|
-
}
|
|
151
|
-
//Since we are attaching to a body we need to send the correct styles from the target portion of the dom to the portal element
|
|
152
|
-
let computedStyle = getComputedStyle(this)
|
|
153
|
-
let styles = {
|
|
154
|
-
"--spectric-primary": computedStyle.getPropertyValue("--spectric-primary"),
|
|
155
|
-
"--spectric-background-inverse": computedStyle.getPropertyValue("--spectric-background-inverse"),
|
|
156
|
-
"--spectric-background-hover": computedStyle.getPropertyValue("--spectric-background-hover"),
|
|
157
|
-
"--spectric-text-on-color": computedStyle.getPropertyValue("--spectric-text-on-color"),
|
|
158
|
-
"--spectric-border-radius": computedStyle.getPropertyValue("--spectric-border-radius"),
|
|
159
|
-
}
|
|
160
|
-
const bounds = this.target.getBoundingClientRect()
|
|
161
|
-
const portalBounds = this.portalElement.getBoundingClientRect()
|
|
162
|
-
if (this.target !== document.body) {
|
|
163
|
-
if (this.maxWidth && this.maxWidth > 0) {
|
|
164
|
-
portalBounds.width = Math.min(portalBounds.width, this.maxWidth)
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
let location: {
|
|
168
|
-
left: string;
|
|
169
|
-
top: string;
|
|
170
|
-
};
|
|
171
|
-
if (this.position === "mouse" && this.mouseLocation) {
|
|
172
|
-
this.mouseframe = undefined
|
|
173
|
-
location = { left: this.mouseLocation.left + 10 + "px", top: this.mouseLocation.top - (portalBounds.height / 2) + "px" }
|
|
174
|
-
} else if (this.position === "top") {
|
|
175
|
-
location = {
|
|
176
|
-
top: bounds.top - portalBounds.height + "px",
|
|
177
|
-
left: (bounds.left + (bounds.width / 2)) - (portalBounds.width / 2) + "px"
|
|
178
|
-
}
|
|
179
|
-
} else if (this.position === "bottom") {
|
|
180
|
-
location = {
|
|
181
|
-
top: bounds.bottom + "px",
|
|
182
|
-
left: (bounds.left + (bounds.width / 2)) - (portalBounds.width / 2) + "px"
|
|
183
|
-
}
|
|
184
|
-
} else if (this.position === "left") {
|
|
185
|
-
location = {
|
|
186
|
-
top: Math.max(0, bounds.top + bounds.height / 2 - portalBounds.height / 2) + "px",
|
|
187
|
-
left: bounds.left - (portalBounds.width) + "px"
|
|
188
|
-
}
|
|
189
|
-
} else if (this.position === "right") {
|
|
190
|
-
location = {
|
|
191
|
-
top: Math.max(0, bounds.top + bounds.height / 2 - portalBounds.height / 2) + "px",
|
|
192
|
-
left: bounds.right + "px"
|
|
193
|
-
}
|
|
194
|
-
} else {
|
|
195
|
-
location = { left: "0px", top: "0px" };
|
|
196
|
-
console.error("Unknown position... Maybe we sould implement auto?")
|
|
197
|
-
}
|
|
198
|
-
this.applyStyle({ ...styles, ...location })
|
|
199
|
-
if (this.position !== "mouse") {
|
|
200
|
-
this.portalElement.animate({ opacity: [0, 1] }, { duration: this.animationDuration })
|
|
201
|
-
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Public method to trigger showing the tooltip programatically
|
|
90
|
+
*/
|
|
91
|
+
public async showToolTip() {
|
|
92
|
+
await super.showPopover()
|
|
93
|
+
this.portalElement.classList.add("spectric-tooltip-portal")
|
|
202
94
|
}
|
|
95
|
+
|
|
203
96
|
protected render() {
|
|
204
97
|
//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.
|
|
205
98
|
// See showTooltip for the real rendering
|
package/src/index.ts
CHANGED
|
@@ -1 +1,8 @@
|
|
|
1
|
-
export * from "./components"
|
|
1
|
+
export * from "./components"
|
|
2
|
+
export * from "./classes"
|
|
3
|
+
export * from "./utils"
|
|
4
|
+
import * as classes from "./classes"
|
|
5
|
+
import * as components from "./components"
|
|
6
|
+
import * as utils from "./utils"
|
|
7
|
+
const module = { ...classes, ...components, ...utils }
|
|
8
|
+
export default module
|
|
@@ -7,9 +7,9 @@ import { html, LitElement } from 'lit';
|
|
|
7
7
|
|
|
8
8
|
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
9
9
|
import "./lorumipsum"
|
|
10
|
-
import {
|
|
10
|
+
import { PaginationProps } from "../../components/pagination";
|
|
11
11
|
import { FilterEvent } from "../../components/table/cell";
|
|
12
|
-
import { TableDataOptions,
|
|
12
|
+
import { TableDataOptions, SpectricTableElement } from "../../components/table";
|
|
13
13
|
type Props = {
|
|
14
14
|
frameWidth: number
|
|
15
15
|
}
|
|
@@ -24,7 +24,7 @@ export class SpectricStorybookExampleContent extends LitElement implements Props
|
|
|
24
24
|
@query("spectric-query")
|
|
25
25
|
query!: SpectricQuery
|
|
26
26
|
|
|
27
|
-
private dataSorter =
|
|
27
|
+
private dataSorter = SpectricTableElement.getDefaultDataSorterAndPaginatior<TestData>(tabledata)
|
|
28
28
|
@state()
|
|
29
29
|
dialogOpen: boolean = false;
|
|
30
30
|
get tableData() {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/web-components";
|
|
2
2
|
|
|
3
|
-
import { ColumnSettings, PaginationChangeProps, TableElement, TableSelectOptions, TableSortDirection, TableSortOption, type TableProps as Props } from "../components/";
|
|
3
|
+
//import { ColumnSettings, PaginationChangeProps, TableElement, TableSelectOptions, TableSortDirection, TableSortOption, type TableProps as Props } from "../components/";
|
|
4
4
|
import { html } from "lit";
|
|
5
|
-
import
|
|
5
|
+
import { ColumnSettings, PaginationChangeProps, SpectricTableElement, TableDataOptions, TableSelectOptions, TableSortDirection, TableSortOption, type TableProps as Props } from "../index"
|
|
6
6
|
import { ifDefined } from "lit/directives/if-defined.js";
|
|
7
7
|
import { useArgs } from "@storybook/client-api";
|
|
8
8
|
import { FilterEvent, rowGetValue } from "../components/table/cell";
|
|
@@ -10,7 +10,7 @@ import { tablecolumns, tabledata } from "./fixtures/data";
|
|
|
10
10
|
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
11
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
|
-
const getData =
|
|
13
|
+
const getData = SpectricTableElement.getDefaultDataSorterAndPaginatior<typeof tabledata[0]>(data)
|
|
14
14
|
const meta = {
|
|
15
15
|
title: "UI/Table",
|
|
16
16
|
tags: ["autodocs"],
|
|
@@ -31,10 +31,10 @@ const meta = {
|
|
|
31
31
|
@filter=${(e: CustomEvent<FilterEvent<any>>) => {
|
|
32
32
|
alert(`filter ${e.detail.include ? "for" : "out"} event value ${e.detail.value}`)
|
|
33
33
|
}}
|
|
34
|
-
@change=${(e: CustomEvent<
|
|
34
|
+
@change=${(e: CustomEvent<TableDataOptions<typeof tabledata[0]>>) => {
|
|
35
35
|
console.log(e)
|
|
36
36
|
updateArgs({ ...e.detail });
|
|
37
|
-
if (e.target && e.target instanceof
|
|
37
|
+
if (e.target && e.target instanceof SpectricTableElement) {
|
|
38
38
|
e.target.data = getData({ ...args, ...e.detail })
|
|
39
39
|
}
|
|
40
40
|
}}
|