@spectric/ui 0.0.8 → 0.0.9
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 +5 -28
- package/dist/components/Button.d.ts +6 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/input.d.ts +5 -1
- package/dist/components/table/body.d.ts +1 -1
- package/dist/components/table/cell.d.ts +6 -1
- package/dist/components/table/table.d.ts +11 -1
- package/dist/components/tooltip/index.d.ts +1 -0
- package/dist/components/tooltip/tooltip.d.ts +95 -0
- package/dist/custom-elements.json +103 -8
- package/dist/index.es.js +1828 -1645
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +116 -83
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/Button.ts +12 -1
- package/src/components/button.css.ts +19 -2
- package/src/components/index.ts +2 -1
- package/src/components/input.css +6 -1
- package/src/components/input.ts +26 -5
- package/src/components/pagination/pagination.ts +3 -3
- package/src/components/table/body.ts +2 -2
- package/src/components/table/cell.ts +21 -5
- package/src/components/table/table.css +12 -2
- package/src/components/table/table.ts +46 -3
- package/src/components/tooltip/index.ts +1 -0
- package/src/components/tooltip/tooltip.css +52 -0
- package/src/components/tooltip/tooltip.ts +228 -0
- package/src/docs/HTML-Vue-Python Integration.mdx +18 -0
- package/src/docs/React.mdx +20 -0
- package/src/docs/welcome.mdx +29 -0
- package/src/stories/Button.stories.ts +22 -0
- package/src/stories/fixtures/ExampleContent.ts +39 -4
- package/src/stories/fixtures/data.ts +20 -2
- package/src/stories/table.stories.ts +27 -13
- package/src/stories/tooltip.stories.ts +68 -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 spectric-button{position:absolute;right:4px;bottom:3px}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}spectric-table tr{text-align:center}spectric-table-header{display:table-header-group}spectric-table div[role=table]{display:table}spectric-table-body{display:table-row-group}spectric-table-cell{display:contents}spectric-table-cell td{position:relative}spectric-table .filterable{
|
|
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}spectric-table tr{text-align:center}spectric-table-body tr:hover{background-color:color-mix(in srgb,var(--spectric-primary, #1ea7fd),transparent 70%)}spectric-table-header{display:table-header-group;font-weight:700}spectric-table div[role=table]{display:table}spectric-table-body{display:table-row-group}spectric-table-cell{display:contents;vertical-align:middle}spectric-table-cell td{position:relative}spectric-table td:hover:has(.filterable){border:1px solid var(--spectric-primary, #1ea7fd)}spectric-table td{border:1px solid transparent}spectric-table-cell .table-cell-actions{position:absolute;display:flex;width:100%;flex-direction:row-reverse;visibility:hidden;top:-10px}spectric-table-cell td:hover .table-cell-actions{visibility:unset}.spectric-tooltip-portal{position:fixed;z-index:9999;pointer-events:none;--spectric-tooltip-background: color-mix(in srgb,var(--spectric-background-inverse,#f4f4f4) 100%,var(--spectric-primary,#1ea7fd) 90%) }.spectric-tooltip-portal .tooltip-container{display:flex;justify-content:center;align-items:center}.spectric-tooltip-portal.top .tooltip-container{flex-direction:column-reverse}.spectric-tooltip-portal.bottom .tooltip-container{flex-direction:column}.spectric-tooltip-portal.left .tooltip-container{flex-direction:row-reverse}.spectric-tooltip-portal .tooltip-content{background:var(--spectric-tooltip-background);border-radius:var(--spectric-border-radius,.4em);box-shadow:0 0 .01em .01em color-mix(in srgb,var(--spectric-background-hover,rgba(141, 141, 141, .12)) 90%,var(--spectric-text-on-color,#ffffff) 90%);padding:.2em;color:var(--spectric-text-on-color,#ffffff)}.spectric-tooltip-portal .tooltip-caret{background:var(--spectric-tooltip-background)}.spectric-tooltip-portal.top .tooltip-caret,.spectric-tooltip-portal.bottom .tooltip-caret{inline-size:.75rem;block-size:.374rem}.spectric-tooltip-portal.left .tooltip-caret,.spectric-tooltip-portal.right .tooltip-caret{inline-size:.375rem;block-size:.75rem}.spectric-tooltip-portal.top .tooltip-caret{clip-path:polygon(0 0,50% 100%,100% 0)}.spectric-tooltip-portal.bottom .tooltip-caret{clip-path:polygon(0 100%,50% 0,100% 100%)}.spectric-tooltip-portal.left .tooltip-caret{clip-path:polygon(0 0,100% 50%,0 100%)}.spectric-tooltip-portal.right .tooltip-caret{clip-path:polygon(0 50%,100% 0,100% 100%)}
|
package/package.json
CHANGED
package/src/components/Button.ts
CHANGED
|
@@ -4,6 +4,8 @@ import { styleMap } from 'lit/directives/style-map.js';
|
|
|
4
4
|
import style from './button.css';
|
|
5
5
|
import { customElement, property } from 'lit/decorators.js';
|
|
6
6
|
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from './types';
|
|
7
|
+
import { DomRenderable } from './table';
|
|
8
|
+
import { TooltipPostionsTypes } from './tooltip';
|
|
7
9
|
|
|
8
10
|
export enum ButtonSizes {
|
|
9
11
|
large = "large",
|
|
@@ -33,6 +35,8 @@ export interface ButtonProps {
|
|
|
33
35
|
disabled: boolean;
|
|
34
36
|
danger?: boolean;
|
|
35
37
|
icon?: boolean
|
|
38
|
+
tooltip?: DomRenderable
|
|
39
|
+
tooltipPosition?: TooltipPostionsTypes
|
|
36
40
|
}
|
|
37
41
|
const MODES = {
|
|
38
42
|
"primary": 'spectric-button--primary',
|
|
@@ -58,7 +62,10 @@ export class SpectricButton extends LitElement implements ButtonProps {
|
|
|
58
62
|
danger = false;
|
|
59
63
|
@property({ type: Boolean, reflect: true })
|
|
60
64
|
icon: boolean = false;
|
|
61
|
-
|
|
65
|
+
@property({ type: String, reflect: true })
|
|
66
|
+
tooltip?: DomRenderable;
|
|
67
|
+
@property({ type: String, reflect: true })
|
|
68
|
+
tooltipPosition?: TooltipPostionsTypes = "right";
|
|
62
69
|
connectedCallback(): void {
|
|
63
70
|
super.connectedCallback()
|
|
64
71
|
this.addEventListener("click", this._onClick, { capture: true })
|
|
@@ -74,6 +81,9 @@ export class SpectricButton extends LitElement implements ButtonProps {
|
|
|
74
81
|
e.preventDefault()
|
|
75
82
|
e.stopImmediatePropagation()
|
|
76
83
|
e.stopPropagation()
|
|
84
|
+
if (this.disabled) {
|
|
85
|
+
return
|
|
86
|
+
}
|
|
77
87
|
const options: CustomEventInit = {
|
|
78
88
|
bubbles: true,
|
|
79
89
|
composed: true,
|
|
@@ -85,6 +95,7 @@ export class SpectricButton extends LitElement implements ButtonProps {
|
|
|
85
95
|
protected render(): unknown {
|
|
86
96
|
const mode = MODES[this.variant] || 'spectric-button--primary';
|
|
87
97
|
return html`
|
|
98
|
+
${this.tooltip ? html`<spectric-tooltip .text=${this.tooltip} .position=${this.tooltipPosition || "right"} .triggerTarget=${this}></spectric-tooltip>` : null}
|
|
88
99
|
<button
|
|
89
100
|
type="button"
|
|
90
101
|
?disabled=${this.disabled}
|
|
@@ -22,9 +22,15 @@ export default css`
|
|
|
22
22
|
--button-primary-hover: var(--spectric-button-primary-hover, #0050e6);
|
|
23
23
|
--button-secondary-hover: var(--spectric-button-secondary-hover, #474747);
|
|
24
24
|
--button-tertiary-hover: var(--spectric-button-tertiary-hover, #0050e6);
|
|
25
|
-
--button-disabled: var(--spectric-button-disabled, #
|
|
25
|
+
--button-disabled: var(--spectric-button-disabled, #cfcbcb4d);
|
|
26
|
+
}
|
|
27
|
+
:host([disabled]) {
|
|
28
|
+
cursor: not-allowed;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
:host([disabled]) .animation{
|
|
32
|
+
visibility:hidden;
|
|
26
33
|
}
|
|
27
|
-
:host([disabled]) { pointer-events: none }
|
|
28
34
|
|
|
29
35
|
.spectric-button {
|
|
30
36
|
pointer-events:none;
|
|
@@ -83,8 +89,14 @@ export default css`
|
|
|
83
89
|
display: flex;
|
|
84
90
|
align-items: center;
|
|
85
91
|
justify-content: center;
|
|
92
|
+
-webkit-user-select: none; /* For Safari */
|
|
93
|
+
-moz-user-select: none; /* For Firefox */
|
|
94
|
+
-ms-user-select: none; /* For IE 10+ */
|
|
95
|
+
user-select: none; /* Standard syntax */
|
|
86
96
|
}
|
|
87
97
|
|
|
98
|
+
|
|
99
|
+
|
|
88
100
|
/* :host([icon][size="small"]){
|
|
89
101
|
height:12px;
|
|
90
102
|
width:12px;
|
|
@@ -132,6 +144,11 @@ export default css`
|
|
|
132
144
|
/* background-color:var(--button-disabled); */
|
|
133
145
|
color:var(--text-on-color-disabled);
|
|
134
146
|
}
|
|
147
|
+
.spectric-button.spectric-button--primary:disabled{
|
|
148
|
+
|
|
149
|
+
background-color:var(--button-disabled);
|
|
150
|
+
|
|
151
|
+
}
|
|
135
152
|
.spectric-button:disabled .animation , :host(:disabled:hover) .animation{
|
|
136
153
|
background-color: rgba(0, 0, 0, 0);
|
|
137
154
|
opacity:1
|
package/src/components/index.ts
CHANGED
package/src/components/input.css
CHANGED
|
@@ -68,8 +68,13 @@ spectric-input #helper-text {
|
|
|
68
68
|
height: 18px;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
spectric-input spectric-button {
|
|
71
|
+
spectric-input[variant="password"] spectric-button {
|
|
72
72
|
position: absolute;
|
|
73
73
|
right: 4px;
|
|
74
74
|
bottom: 3px;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
spectric-input .checkbox{
|
|
78
|
+
display: flex;
|
|
79
|
+
justify-self: center;
|
|
75
80
|
}
|
package/src/components/input.ts
CHANGED
|
@@ -3,6 +3,7 @@ import "./input.css"
|
|
|
3
3
|
import { customElement, property, query } from 'lit/decorators.js';
|
|
4
4
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
5
5
|
import { ReactElementWithPropsAndEvents } from './types';
|
|
6
|
+
import { ButtonSizesTypes } from './Button';
|
|
6
7
|
|
|
7
8
|
export enum InputVariants {
|
|
8
9
|
Text = 'text',
|
|
@@ -16,6 +17,7 @@ export enum InputVariants {
|
|
|
16
17
|
file = "file",//display drop area
|
|
17
18
|
hidden = "hidden",//display drop area
|
|
18
19
|
password = "password",
|
|
20
|
+
checkbox = "checkbox"
|
|
19
21
|
|
|
20
22
|
}
|
|
21
23
|
type InputVariantsTypes = `${InputVariants}`
|
|
@@ -73,6 +75,9 @@ export interface InputProps {
|
|
|
73
75
|
}
|
|
74
76
|
@customElement('spectric-input')
|
|
75
77
|
export class SpectricInput extends LitElement implements InputProps {
|
|
78
|
+
@property({ type: Boolean, reflect: true })
|
|
79
|
+
checked?: boolean;
|
|
80
|
+
size?: ButtonSizesTypes;
|
|
76
81
|
//static styles?: CSSResultGroup | undefined = style;
|
|
77
82
|
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
78
83
|
return this
|
|
@@ -155,7 +160,7 @@ export class SpectricInput extends LitElement implements InputProps {
|
|
|
155
160
|
@property({ reflect: true })
|
|
156
161
|
autocomplete: HTMLInputElement['autocomplete'] = "";
|
|
157
162
|
get selectionStart() {
|
|
158
|
-
if(!this._input){
|
|
163
|
+
if (!this._input) {
|
|
159
164
|
return null
|
|
160
165
|
}
|
|
161
166
|
return this._input.selectionStart
|
|
@@ -187,20 +192,20 @@ export class SpectricInput extends LitElement implements InputProps {
|
|
|
187
192
|
}
|
|
188
193
|
}
|
|
189
194
|
blur(): void {
|
|
190
|
-
if(this._input){
|
|
195
|
+
if (this._input) {
|
|
191
196
|
this._input.blur()
|
|
192
197
|
}
|
|
193
198
|
}
|
|
194
199
|
focus(options?: FocusOptions): void {
|
|
195
|
-
if(this._input){
|
|
200
|
+
if (this._input) {
|
|
196
201
|
//Sometimes the input will get auto focused after a modal closes but the cursor isn't set. we need to blur then refocus to get the cursor
|
|
197
202
|
this._input.blur()
|
|
198
203
|
this._input.focus(options)
|
|
199
204
|
}
|
|
200
205
|
}
|
|
201
206
|
setSelectionRange(start: number, end: number, direction: "forward" | "backward" | "none" = "none") {
|
|
202
|
-
if(!this._input){
|
|
203
|
-
return
|
|
207
|
+
if (!this._input) {
|
|
208
|
+
return
|
|
204
209
|
}
|
|
205
210
|
this._input.setSelectionRange(start, end, direction)
|
|
206
211
|
}
|
|
@@ -290,6 +295,22 @@ export class SpectricInput extends LitElement implements InputProps {
|
|
|
290
295
|
|
|
291
296
|
case InputVariants.hidden:
|
|
292
297
|
return html`<input type="hidden"></input>`
|
|
298
|
+
|
|
299
|
+
case InputVariants.checkbox:
|
|
300
|
+
|
|
301
|
+
return html`
|
|
302
|
+
<div class="checkbox">
|
|
303
|
+
<spectric-button @click=${() => {
|
|
304
|
+
this.checked = !this.checked;
|
|
305
|
+
this.value = Boolean(this.checked);
|
|
306
|
+
console.log(this.checked, this.value)
|
|
307
|
+
this.dispatchEvent(new Event("change", { bubbles: true }))
|
|
308
|
+
}} icon size=${this.size || "xxsmall"} variant=${this.checked ? "primary" : "secondary"}>${this.checked ? '✓' : "\u00A0"}</spectric-button>
|
|
309
|
+
${this.invalid || this.helperText ? html`<spectric-tooltip text=${this.invalid || this.helperText}></spectric-tooltip>` : null}
|
|
310
|
+
${this.label}
|
|
311
|
+
</div>
|
|
312
|
+
</label>
|
|
313
|
+
`
|
|
293
314
|
default:
|
|
294
315
|
break;
|
|
295
316
|
}
|
|
@@ -41,7 +41,7 @@ export class PaginationElement extends LitElement implements PaginationProps {
|
|
|
41
41
|
* Size of the pagination buttons
|
|
42
42
|
*/
|
|
43
43
|
@property({ type: String, reflect: true })
|
|
44
|
-
size: ButtonSizesTypes = "
|
|
44
|
+
size: ButtonSizesTypes = "xsmall"
|
|
45
45
|
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
46
46
|
return this
|
|
47
47
|
}
|
|
@@ -93,8 +93,8 @@ export class PaginationElement extends LitElement implements PaginationProps {
|
|
|
93
93
|
${pageText}
|
|
94
94
|
</div>
|
|
95
95
|
<div>
|
|
96
|
-
<spectric-button size=${this.size} ?disabled=${this.page === 1} @click=${this._handlePageDown}><</spectric-button>
|
|
97
|
-
<spectric-button size=${this.size} ?disabled=${nextPageDisabled} @click=${this._handlePageUp}>></spectric-button>
|
|
96
|
+
<spectric-button size=${this.size} ?disabled=${this.page === 1} @click=${this._handlePageDown} icon><</spectric-button>
|
|
97
|
+
<spectric-button size=${this.size} ?disabled=${nextPageDisabled} @click=${this._handlePageUp} icon>></spectric-button>
|
|
98
98
|
</div>
|
|
99
99
|
</div>
|
|
100
100
|
`: null}
|
|
@@ -12,7 +12,7 @@ interface BodyProps<T> {
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Table Body Element
|
|
16
16
|
*/
|
|
17
17
|
@customElement(TableBodyElementTag)
|
|
18
18
|
export class TableBodyElement<T> extends LitElement implements BodyProps<T> {
|
|
@@ -29,7 +29,7 @@ export class TableBodyElement<T> extends LitElement implements BodyProps<T> {
|
|
|
29
29
|
<body>
|
|
30
30
|
${this.data.map((row: any) => {
|
|
31
31
|
return html`<tr>${this.columns.map(col => {
|
|
32
|
-
return html`<spectric-table-cell .column=${col} .row=${row}></spectric-table-cell>`
|
|
32
|
+
return html`<spectric-table-cell .column=${col} .row=${row} .columns=${this.columns}></spectric-table-cell>`
|
|
33
33
|
})}</tr>`
|
|
34
34
|
})}
|
|
35
35
|
</body>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { html, LitElement } from 'lit';
|
|
2
|
-
import { customElement, property, } from 'lit/decorators.js';
|
|
1
|
+
import { html, LitElement, PropertyValues } from 'lit';
|
|
2
|
+
import { customElement, property, query, } from 'lit/decorators.js';
|
|
3
3
|
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from '../types';
|
|
4
4
|
export const TableCellElementTag = "spectric-table-cell"
|
|
5
5
|
import { ColumnSettings, TableElement } from './table';
|
|
@@ -25,7 +25,18 @@ export class TableCellElement<T> extends LitElement implements CellProps<T> {
|
|
|
25
25
|
row!: T;
|
|
26
26
|
@property({ type: Object, attribute: false })
|
|
27
27
|
column!: ColumnSettings<T>;
|
|
28
|
+
columns!: ColumnSettings<T>[];
|
|
28
29
|
table!: TableElement<T>
|
|
30
|
+
styleRules: CSSStyleDeclaration;
|
|
31
|
+
@query("td")
|
|
32
|
+
td!: HTMLTableCellElement
|
|
33
|
+
constructor() {
|
|
34
|
+
super()
|
|
35
|
+
this.styleRules = document.createElement('span').style;
|
|
36
|
+
}
|
|
37
|
+
protected updated(_changedProperties: PropertyValues): void {
|
|
38
|
+
Object.assign(this.td.style, this.styleRules)
|
|
39
|
+
}
|
|
29
40
|
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
30
41
|
return this
|
|
31
42
|
}
|
|
@@ -74,9 +85,14 @@ export class TableCellElement<T> extends LitElement implements CellProps<T> {
|
|
|
74
85
|
if (this.column.filterable) {
|
|
75
86
|
classes.push("filterable")
|
|
76
87
|
}
|
|
77
|
-
let filterButtons = html`<div class="table-cell-actions"
|
|
78
|
-
|
|
79
|
-
|
|
88
|
+
let filterButtons = html`<div class="table-cell-actions">
|
|
89
|
+
<spectric-button @click=${this._handleFilterOut} size="tiny" variant="text" icon tooltip="Filter Out Value">-</spectric-button>
|
|
90
|
+
<spectric-button @click=${this._handleFilterFor} size="tiny" variant="text" icon tooltip="Filter For Value">+</spectric-button></div>`
|
|
91
|
+
this.styleRules = {
|
|
92
|
+
...this.styleRules,
|
|
93
|
+
width: this.column.width ? this.column.width + "px" : "",
|
|
94
|
+
whiteSpace: this.column.whiteSpace || ""
|
|
95
|
+
}
|
|
80
96
|
return html`
|
|
81
97
|
<td>
|
|
82
98
|
${this.column.filterable ? filterButtons : null}
|
|
@@ -6,8 +6,12 @@ spectric-table tr{
|
|
|
6
6
|
text-align: center;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
spectric-table-body tr:hover{
|
|
10
|
+
background-color: color-mix(in srgb, var(--spectric-primary, #1ea7fd), transparent 70%)
|
|
11
|
+
}
|
|
9
12
|
spectric-table-header{
|
|
10
13
|
display: table-header-group;
|
|
14
|
+
font-weight: bold;
|
|
11
15
|
}
|
|
12
16
|
spectric-table div[role="table"]{
|
|
13
17
|
display: table;
|
|
@@ -17,12 +21,17 @@ spectric-table-body {
|
|
|
17
21
|
}
|
|
18
22
|
spectric-table-cell{
|
|
19
23
|
display: contents;
|
|
24
|
+
vertical-align: middle;
|
|
20
25
|
}
|
|
21
26
|
spectric-table-cell td{
|
|
22
27
|
position: relative;
|
|
23
28
|
}
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
|
|
30
|
+
spectric-table td:hover:has(.filterable) {
|
|
31
|
+
border: 1px solid var(--spectric-primary, #1ea7fd);
|
|
32
|
+
}
|
|
33
|
+
spectric-table td {
|
|
34
|
+
border: 1px solid transparent;
|
|
26
35
|
}
|
|
27
36
|
spectric-table-cell .table-cell-actions{
|
|
28
37
|
position: absolute;
|
|
@@ -30,6 +39,7 @@ spectric-table-cell .table-cell-actions{
|
|
|
30
39
|
width: 100%;
|
|
31
40
|
flex-direction: row-reverse;
|
|
32
41
|
visibility: hidden;
|
|
42
|
+
top: -10px;
|
|
33
43
|
}
|
|
34
44
|
spectric-table-cell td:hover .table-cell-actions{
|
|
35
45
|
visibility: unset;
|
|
@@ -2,7 +2,7 @@ import { html, LitElement, TemplateResult } from 'lit';
|
|
|
2
2
|
import "../pagination";
|
|
3
3
|
import "./header"
|
|
4
4
|
import "./body"
|
|
5
|
-
import { customElement, property, } from 'lit/decorators.js';
|
|
5
|
+
import { customElement, property, state, } from 'lit/decorators.js';
|
|
6
6
|
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from '../types';
|
|
7
7
|
import "./table.css"
|
|
8
8
|
export const TableElementTag = "spectric-table"
|
|
@@ -14,19 +14,26 @@ export type { TableProps, TableEvents }
|
|
|
14
14
|
export type DomRenderable = HTMLElement | TemplateResult | string | number | null
|
|
15
15
|
|
|
16
16
|
export type ColumnSettings<T> = {
|
|
17
|
+
width?: number
|
|
18
|
+
whiteSpace?: "nowrap";
|
|
17
19
|
hidden?: boolean
|
|
18
20
|
sortable?: boolean
|
|
19
21
|
filterable?: boolean
|
|
20
|
-
title?:
|
|
22
|
+
title?: DomRenderable
|
|
21
23
|
key?: string
|
|
22
24
|
render?: (row: T, table: TableElement<T>) => DomRenderable
|
|
23
25
|
}
|
|
26
|
+
type TableSelectOptions = "multi" | "single"
|
|
24
27
|
interface TableProps<T> {
|
|
25
28
|
pagination?: PaginationProps
|
|
26
29
|
columns: ColumnSettings<T>[]
|
|
27
30
|
data: T[]
|
|
31
|
+
select?: TableSelectOptions
|
|
28
32
|
}
|
|
29
33
|
|
|
34
|
+
type DomEvent<T> = Event & {
|
|
35
|
+
target: T
|
|
36
|
+
}
|
|
30
37
|
/**
|
|
31
38
|
* Table Element
|
|
32
39
|
*
|
|
@@ -66,6 +73,8 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
|
|
|
66
73
|
pagination?: PaginationProps | undefined;
|
|
67
74
|
@property({ attribute: false })
|
|
68
75
|
columns: ColumnSettings<T>[] = [];
|
|
76
|
+
@property({ type: String, reflect: false })
|
|
77
|
+
select?: TableSelectOptions;
|
|
69
78
|
private _handlePaginationChange = (e: CustomEvent<PaginationChangeProps>) => {
|
|
70
79
|
e.preventDefault()
|
|
71
80
|
e.stopPropagation()
|
|
@@ -84,12 +93,46 @@ export class TableElement<T> extends LitElement implements TableProps<T> {
|
|
|
84
93
|
//This is only here to document events that bubble up from lower components
|
|
85
94
|
this.dispatchEvent(new CustomEvent<FilterEvent<T>>("filter"))
|
|
86
95
|
}
|
|
96
|
+
@state()
|
|
97
|
+
selected: T[] = [];
|
|
87
98
|
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
88
99
|
return this
|
|
89
100
|
}
|
|
90
|
-
|
|
101
|
+
_handleSelectAllChange = (e: DomEvent<HTMLInputElement>) => {
|
|
102
|
+
e.stopPropagation()
|
|
103
|
+
if (e.target.checked) {
|
|
104
|
+
this.selected = [...this.data]
|
|
105
|
+
} else {
|
|
106
|
+
this.selected = []
|
|
107
|
+
}
|
|
108
|
+
this.dispatchEvent(new CustomEvent("select", { detail: this.selected }))
|
|
109
|
+
}
|
|
91
110
|
protected render(): unknown {
|
|
92
111
|
let columns = this.columns.filter(column => !column.hidden)
|
|
112
|
+
if (this.select) {
|
|
113
|
+
columns.unshift({
|
|
114
|
+
title: this.select === "multi" ? html`<spectric-input variant="checkbox" @change=${this._handleSelectAllChange} .helperText=${"Select All"}></spectric-input>` : null,
|
|
115
|
+
render: (row) => {
|
|
116
|
+
return html`<spectric-input variant="checkbox" .checked=${this.selected.includes(row)} @change=${(e: DomEvent<HTMLInputElement>) => {
|
|
117
|
+
e.stopPropagation()
|
|
118
|
+
if (this.select === "single") {
|
|
119
|
+
this.selected = []
|
|
120
|
+
}
|
|
121
|
+
if (e.target.checked) {
|
|
122
|
+
this.selected.push(row)
|
|
123
|
+
this.dispatchEvent(new CustomEvent("select", { detail: this.selected }))
|
|
124
|
+
} else {
|
|
125
|
+
let index = this.selected.findIndex(value => value === row)
|
|
126
|
+
if (index !== -1) {
|
|
127
|
+
this.selected.splice(index, 1)
|
|
128
|
+
this.dispatchEvent(new CustomEvent("select", { detail: this.selected }))
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}}></spectric-input>`
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
93
136
|
return html`
|
|
94
137
|
<div role="table">
|
|
95
138
|
<spectric-table-header .columns=${columns}></spectric-table-header>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./tooltip"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
.spectric-tooltip-portal{
|
|
2
|
+
position: fixed;
|
|
3
|
+
z-index: 9999;
|
|
4
|
+
pointer-events: none;
|
|
5
|
+
--spectric-tooltip-background: color-mix(in srgb,var(--spectric-background-inverse,#f4f4f4) 100%,var(--spectric-primary,#1ea7fd) 90%)
|
|
6
|
+
}
|
|
7
|
+
.spectric-tooltip-portal .tooltip-container{
|
|
8
|
+
display: flex;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
align-items: center;
|
|
11
|
+
}
|
|
12
|
+
.spectric-tooltip-portal.top .tooltip-container{
|
|
13
|
+
flex-direction: column-reverse;
|
|
14
|
+
}
|
|
15
|
+
.spectric-tooltip-portal.bottom .tooltip-container{
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
}
|
|
18
|
+
.spectric-tooltip-portal.left .tooltip-container{
|
|
19
|
+
flex-direction: row-reverse;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.spectric-tooltip-portal .tooltip-content{
|
|
23
|
+
background: var(--spectric-tooltip-background);
|
|
24
|
+
border-radius: var(--spectric-border-radius,.4em);
|
|
25
|
+
box-shadow: 0 0 .01em .01em color-mix(in srgb, var(--spectric-background-hover,rgba(141, 141, 141, 0.12)) 90%, var(--spectric-text-on-color,#ffffff) 90%);
|
|
26
|
+
padding: .2em;
|
|
27
|
+
color:var(--spectric-text-on-color,#ffffff);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.spectric-tooltip-portal .tooltip-caret{
|
|
31
|
+
background:var(--spectric-tooltip-background);
|
|
32
|
+
}
|
|
33
|
+
.spectric-tooltip-portal.top .tooltip-caret,.spectric-tooltip-portal.bottom .tooltip-caret{
|
|
34
|
+
inline-size: .75rem;
|
|
35
|
+
block-size: .374rem;
|
|
36
|
+
}
|
|
37
|
+
.spectric-tooltip-portal.left .tooltip-caret,.spectric-tooltip-portal.right .tooltip-caret{
|
|
38
|
+
inline-size: .375rem;
|
|
39
|
+
block-size: .75rem;
|
|
40
|
+
}
|
|
41
|
+
.spectric-tooltip-portal.top .tooltip-caret{
|
|
42
|
+
clip-path: polygon(0 0,50% 100%,100% 0);
|
|
43
|
+
}
|
|
44
|
+
.spectric-tooltip-portal.bottom .tooltip-caret{
|
|
45
|
+
clip-path: polygon(0 100%,50% 0,100% 100%);
|
|
46
|
+
}
|
|
47
|
+
.spectric-tooltip-portal.left .tooltip-caret{
|
|
48
|
+
clip-path: polygon(0 0,100% 50%,0 100%);
|
|
49
|
+
}
|
|
50
|
+
.spectric-tooltip-portal.right .tooltip-caret{
|
|
51
|
+
clip-path: polygon(0 50% ,100% 0, 100% 100%);
|
|
52
|
+
}
|