@spectric/ui 0.0.8 → 0.0.10
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 +8 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/components/input.d.ts +5 -1
- package/dist/components/query_bar/QueryBar.d.ts +4 -4
- 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 +13 -29
- 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 +1833 -1646
- 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 +14 -3
- 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/query_bar/QueryBar.ts +6 -6
- package/src/components/table/body.ts +2 -2
- package/src/components/table/cell.ts +35 -8
- package/src/components/table/table.css +12 -2
- package/src/components/table/table.ts +48 -31
- 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 +22 -2
- package/src/stories/table.stories.ts +29 -21
- package/src/stories/tooltip.stories.ts +68 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
|
|
2
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
+
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from '../types';
|
|
4
|
+
import "./tooltip.css"
|
|
5
|
+
export const TooltipElementTag = "spectric-tooltip"
|
|
6
|
+
import { css, CSSResultGroup, html, LitElement, render } from "lit-element";
|
|
7
|
+
import { DomRenderable } from "../table";
|
|
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 (default:300) you can disable this by setting to 0 or -1
|
|
37
|
+
*/
|
|
38
|
+
maxWidth?: number
|
|
39
|
+
/**
|
|
40
|
+
* Container the tool tip will be attached to. (default:document.body)
|
|
41
|
+
*/
|
|
42
|
+
portalTarget?: HTMLElement
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The element that triggers the tooltip. (default:node.parentElement) 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(TooltipElementTag)
|
|
54
|
+
export class TooltipElement extends LitElement 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
|
+
private portalElement = document.createElement("div")
|
|
66
|
+
private 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
|
+
private timer?: number;
|
|
74
|
+
private open: boolean = false;
|
|
75
|
+
mouseframe?: number;
|
|
76
|
+
@property({ attribute: false })
|
|
77
|
+
triggerTarget?: HTMLElement;
|
|
78
|
+
private get target() {
|
|
79
|
+
return this.triggerTarget || this.parentElement
|
|
80
|
+
}
|
|
81
|
+
connectedCallback(): void {
|
|
82
|
+
super.connectedCallback()
|
|
83
|
+
if (this.target) {
|
|
84
|
+
this.target.addEventListener("mousemove", this._getMousePosition)
|
|
85
|
+
this.target.addEventListener("mouseover", this.showToolTip)
|
|
86
|
+
this.target.addEventListener("mouseleave", this._hideTooltip)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
disconnectedCallback(): void {
|
|
90
|
+
super.connectedCallback()
|
|
91
|
+
this.target?.removeEventListener("mousemove", this._getMousePosition)
|
|
92
|
+
this.target?.removeEventListener("mouseover", this.showToolTip)
|
|
93
|
+
this.target?.removeEventListener("mouseleave", this._hideTooltip)
|
|
94
|
+
this.portalElement.remove()
|
|
95
|
+
}
|
|
96
|
+
private _getMousePosition = (ev: MouseEvent) => {
|
|
97
|
+
this.mouseLocation = {
|
|
98
|
+
left: ev.clientX,
|
|
99
|
+
top: ev.clientY
|
|
100
|
+
}
|
|
101
|
+
if (this.position == "mouse" && this.open && !this.mouseframe) {
|
|
102
|
+
this.mouseframe = requestAnimationFrame(() => this.positionTooltip())
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
_hideTooltip = () => {
|
|
106
|
+
if (this.timer) {
|
|
107
|
+
clearTimeout(this.timer)
|
|
108
|
+
}
|
|
109
|
+
this.open = false
|
|
110
|
+
this.portalElement.remove()
|
|
111
|
+
}
|
|
112
|
+
private showToolTip = async () => {
|
|
113
|
+
if (this.timer) {
|
|
114
|
+
clearTimeout(this.timer)
|
|
115
|
+
}
|
|
116
|
+
await new Promise(resolve => {
|
|
117
|
+
this.timer = window.setTimeout(resolve, this.delay)
|
|
118
|
+
})
|
|
119
|
+
this.portalElement.style.pointerEvents = "none"
|
|
120
|
+
this.portalElement.className = `spectric-tooltip-portal ${this.position}`
|
|
121
|
+
const tooltip = html`<div class="tooltip-container">
|
|
122
|
+
<span class="tooltip-caret"></span>
|
|
123
|
+
<div class="tooltip-content">${this.text}</div>
|
|
124
|
+
</div>`
|
|
125
|
+
render(tooltip, this.portalElement)
|
|
126
|
+
//with the delay it is possible that the triggering element was removed or hidden lets check that it is visible
|
|
127
|
+
if (!this.target || !this.target.checkVisibility()) {
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
//We need to append our tooltip and let the css updates apply before we can take measurements
|
|
131
|
+
this.portalTarget.appendChild(this.portalElement)
|
|
132
|
+
this.open = true
|
|
133
|
+
requestAnimationFrame(this.positionTooltip)
|
|
134
|
+
}
|
|
135
|
+
private applyStyle = (style: Record<string, string>) => {
|
|
136
|
+
Object.entries(style).forEach(([prop, value]) => {
|
|
137
|
+
this.portalElement.style.setProperty(prop, value)
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
private positionTooltip = () => {
|
|
141
|
+
if (!this.target) {
|
|
142
|
+
//We got detached before the animation frame completed
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
//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
|
|
146
|
+
let computedStyle = getComputedStyle(this)
|
|
147
|
+
let styles = {
|
|
148
|
+
"--spectric-primary": computedStyle.getPropertyValue("--spectric-primary"),
|
|
149
|
+
"--spectric-background-inverse": computedStyle.getPropertyValue("--spectric-background-inverse"),
|
|
150
|
+
"--spectric-background-hover": computedStyle.getPropertyValue("--spectric-background-hover"),
|
|
151
|
+
"--spectric-text-on-color": computedStyle.getPropertyValue("--spectric-text-on-color"),
|
|
152
|
+
"--spectric-border-radius": computedStyle.getPropertyValue("--spectric-border-radius"),
|
|
153
|
+
}
|
|
154
|
+
const bounds = this.target.getBoundingClientRect()
|
|
155
|
+
const portalBounds = this.portalElement.getBoundingClientRect()
|
|
156
|
+
if (this.target !== document.body)
|
|
157
|
+
if (this.maxWidth && this.maxWidth > 0) {
|
|
158
|
+
portalBounds.width = Math.min(portalBounds.width, this.maxWidth)
|
|
159
|
+
}
|
|
160
|
+
if (this.position === "mouse" && this.mouseLocation) {
|
|
161
|
+
this.mouseframe = undefined
|
|
162
|
+
const location = { left: this.mouseLocation.left + 10 + "px", top: this.mouseLocation.top - (portalBounds.height / 2) + "px" }
|
|
163
|
+
this.applyStyle({ ...styles, ...location })
|
|
164
|
+
} else if (this.position === "top") {
|
|
165
|
+
const location = {
|
|
166
|
+
top: bounds.top - portalBounds.height + "px",
|
|
167
|
+
left: (bounds.left + (bounds.width / 2)) - (portalBounds.width / 2) + "px"
|
|
168
|
+
}
|
|
169
|
+
this.applyStyle({ ...styles, ...location })
|
|
170
|
+
} else if (this.position === "bottom") {
|
|
171
|
+
const location = {
|
|
172
|
+
top: bounds.bottom + "px",
|
|
173
|
+
left: (bounds.left + (bounds.width / 2)) - (portalBounds.width / 2) + "px"
|
|
174
|
+
}
|
|
175
|
+
this.applyStyle({ ...styles, ...location })
|
|
176
|
+
} else if (this.position === "left") {
|
|
177
|
+
const location = {
|
|
178
|
+
top: Math.max(0, bounds.top + bounds.height / 2 - portalBounds.height / 2) + "px",
|
|
179
|
+
left: bounds.left - (portalBounds.width) + "px"
|
|
180
|
+
}
|
|
181
|
+
this.applyStyle({ ...styles, ...location })
|
|
182
|
+
} else if (this.position === "right") {
|
|
183
|
+
const location = {
|
|
184
|
+
top: Math.max(0, bounds.top + bounds.height / 2 - portalBounds.height / 2) + "px",
|
|
185
|
+
left: bounds.right + "px"
|
|
186
|
+
}
|
|
187
|
+
this.applyStyle({ ...styles, ...location })
|
|
188
|
+
}
|
|
189
|
+
if (this.position !== "mouse") {
|
|
190
|
+
this.portalElement.animate({ opacity: [0, 1] }, { duration: this.animationDuration })
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
protected render() {
|
|
194
|
+
//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.
|
|
195
|
+
// See showTooltip for the real rendering
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
interface TooltipEvents {
|
|
201
|
+
//'open': (event: CustomEvent<{ pagination: PaginationChangeProps }>) => void;
|
|
202
|
+
//'filter': (event: CustomEvent<FilterEvent>) => void;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
declare global {
|
|
206
|
+
interface HTMLElementTagNameMap {
|
|
207
|
+
[TooltipElementTag]: HTMLElementTagWithEvents<TooltipElement, TooltipEvents>
|
|
208
|
+
|
|
209
|
+
}
|
|
210
|
+
namespace JSX {
|
|
211
|
+
interface IntrinsicElements {
|
|
212
|
+
/**
|
|
213
|
+
* @see {@link DialogElement}
|
|
214
|
+
*/
|
|
215
|
+
[TooltipElementTag]: ReactElementWithPropsAndEvents<TooltipElement, TooltipProps, TooltipEvents>;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
namespace React {
|
|
219
|
+
namespace JSX {
|
|
220
|
+
interface IntrinsicElements {
|
|
221
|
+
/**
|
|
222
|
+
* @see {@link DialogElement}
|
|
223
|
+
*/
|
|
224
|
+
[TooltipElementTag]: ReactElementWithPropsAndEvents<TooltipElement, TooltipProps, TooltipEvents>
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# HTML integration
|
|
2
|
+
|
|
3
|
+
Add the dist/custom-element.json to the html.languge settings
|
|
4
|
+
https://code.visualstudio.com/docs/languages/html#_html-custom-data
|
|
5
|
+

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

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

|
|
15
|
+
|
|
16
|
+
# Python Jinja
|
|
17
|
+
|
|
18
|
+
Same as HTML Integration
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# React 19+
|
|
2
|
+
|
|
3
|
+
Has full support for webcomponents and you can use webcomponents exactly the same way you use any react component.
|
|
4
|
+
|
|
5
|
+
There is one small stipulation. Any custom event that isn't in the react.DOMAttributes events (onClick,onBlur,onFocus... ect) will not be auto capitalized and handled as a react synthetic event.
|
|
6
|
+
|
|
7
|
+
What does this mean?
|
|
8
|
+
|
|
9
|
+
This means you will need to write
|
|
10
|
+
|
|
11
|
+
```jsx
|
|
12
|
+
<spectric-page onlogin={()=>}></spectric-page>
|
|
13
|
+
```
|
|
14
|
+
[Example Here](https://stackblitz.com/edit/react-ts-gq8n43qy?file=App.tsx)
|
|
15
|
+
|
|
16
|
+
## React < 19
|
|
17
|
+
|
|
18
|
+
For react < 19 the properties aren't passed down by react so you will need to use the useEffect hook to set the properties after the element has been created.
|
|
19
|
+
|
|
20
|
+
[Example here](https://stackblitz.com/edit/react-ts-oo5hgcp2?file=App.tsx)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Component Examples and playground
|
|
2
|
+
|
|
3
|
+
https://pages.spectric.com/web/spectric-ui/?path=/docs/spectric-ui-components-ui-page--docs
|
|
4
|
+
|
|
5
|
+
# Developing
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
nvm use
|
|
9
|
+
npm start
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
# Publishing
|
|
13
|
+
|
|
14
|
+
To publish a new version run
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
npm version patch
|
|
18
|
+
git push --follow-tags
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This will trigger a pipeline to run and build the source and publish to our internal gitlab NPM
|
|
22
|
+
|
|
23
|
+
# Installing In your project
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
npm i @spectric/ui
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The types files produced when building seemlessly integrate the custom elements into javascript giving full type hinting
|
|
@@ -4,6 +4,7 @@ import { ButtonSizes, ButtonVariants, type ButtonProps } from '../components/But
|
|
|
4
4
|
import '../components';
|
|
5
5
|
import { html } from 'lit';
|
|
6
6
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
7
|
+
import { TooltipPostions } from '../components';
|
|
7
8
|
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
8
9
|
const meta = {
|
|
9
10
|
title: 'UI/Button',
|
|
@@ -136,4 +137,25 @@ export const Dangerous: Story = {
|
|
|
136
137
|
args: {
|
|
137
138
|
danger: true
|
|
138
139
|
},
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export const ButtonsWithTooltips: Story = {
|
|
143
|
+
render: (args) => html`
|
|
144
|
+
${Object.values(TooltipPostions).map(p => {
|
|
145
|
+
return html`
|
|
146
|
+
<spectric-button
|
|
147
|
+
?danger=${args.danger}
|
|
148
|
+
tooltip=${p}
|
|
149
|
+
tooltipPosition=${p}
|
|
150
|
+
size=${ifDefined(args.size)}
|
|
151
|
+
backgroundColor=${ifDefined(args.backgroundColor)}
|
|
152
|
+
@click=${() => { alert("clicked") }}
|
|
153
|
+
>
|
|
154
|
+
${p}
|
|
155
|
+
</spectric-button>`
|
|
156
|
+
})}
|
|
157
|
+
`,
|
|
158
|
+
args: {
|
|
159
|
+
|
|
160
|
+
},
|
|
139
161
|
};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
|
|
2
|
-
import { filterByColumn } from "./data";
|
|
2
|
+
import { filterByColumn, tablecolumns, tabledata } from "./data";
|
|
3
3
|
import { ExampleBits } from "./Bits";
|
|
4
|
-
import { FieldTypes } from "../../components/query_bar/QueryBar";
|
|
4
|
+
import { FieldTypes, SpectricQuery } from "../../components/query_bar/QueryBar";
|
|
5
5
|
|
|
6
6
|
import { html, LitElement } from 'lit';
|
|
7
7
|
|
|
8
|
-
import { customElement, property, state } from 'lit/decorators.js';
|
|
8
|
+
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
9
9
|
import "./lorumipsum"
|
|
10
|
+
import { PaginationChangeProps } from "../../components/pagination";
|
|
11
|
+
import { FilterEvent } from "../../components/table/cell";
|
|
10
12
|
type Props = {
|
|
11
13
|
frameWidth: number
|
|
12
14
|
}
|
|
@@ -17,8 +19,35 @@ export class SpectricStorybookExampleContent extends LitElement implements Props
|
|
|
17
19
|
}
|
|
18
20
|
@property({ type: Number, reflect: true })
|
|
19
21
|
frameWidth: number = 10;
|
|
22
|
+
|
|
23
|
+
@query("spectric-query")
|
|
24
|
+
query!: SpectricQuery
|
|
25
|
+
|
|
20
26
|
@state()
|
|
21
27
|
dialogOpen: boolean = false;
|
|
28
|
+
tableData = tabledata.slice(0, 3)
|
|
29
|
+
pagination = {
|
|
30
|
+
page: 1,
|
|
31
|
+
pageSize: 3,
|
|
32
|
+
size: "xsmall",
|
|
33
|
+
totalItems: tabledata.length,
|
|
34
|
+
}
|
|
35
|
+
_handleFilter = (e: CustomEvent<FilterEvent<any>>) => {
|
|
36
|
+
let include = e.detail.include ? "" : "not "
|
|
37
|
+
if (e.detail.column.key && e.detail.value) {
|
|
38
|
+
if (this.query.value !== "") {
|
|
39
|
+
this.query.value = `${this.query.value} and ${include}${e.detail.column.key}: '${e.detail.value}'`
|
|
40
|
+
} else {
|
|
41
|
+
this.query.value = `${include}${e.detail.column.key}: '${e.detail.value}'`
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
_handlePaginationChange = (e: CustomEvent<{ pagination: PaginationChangeProps }>) => {
|
|
46
|
+
let { pagination } = e.detail
|
|
47
|
+
this.pagination = { ...this.pagination, ...pagination }
|
|
48
|
+
this.tableData = tabledata.slice((pagination.page - 1) * pagination.pageSize, (pagination.page) * pagination.pageSize)
|
|
49
|
+
this.requestUpdate()
|
|
50
|
+
}
|
|
22
51
|
render() {
|
|
23
52
|
return html`
|
|
24
53
|
<spectric-dialog
|
|
@@ -59,6 +88,12 @@ export class SpectricStorybookExampleContent extends LitElement implements Props
|
|
|
59
88
|
>
|
|
60
89
|
|
|
61
90
|
</spectric-query>
|
|
91
|
+
<spectric-table
|
|
92
|
+
.data=${this.tableData}
|
|
93
|
+
.columns=${tablecolumns}
|
|
94
|
+
@filter=${this._handleFilter}
|
|
95
|
+
@change=${this._handlePaginationChange}
|
|
96
|
+
.pagination=${this.pagination}></spectric-table>
|
|
62
97
|
<spectric-panel style="display:flex">
|
|
63
98
|
<spectric-bit-display
|
|
64
99
|
frameWidth=${this.frameWidth}
|
|
@@ -92,7 +127,7 @@ export class SpectricStorybookExampleContent extends LitElement implements Props
|
|
|
92
127
|
<spectric-button size="small" danger @click=${() => {
|
|
93
128
|
this.dialogOpen = true
|
|
94
129
|
this.requestUpdate()
|
|
95
|
-
}}>Delete</spectric-button>
|
|
130
|
+
}}>Delete (show modal)</spectric-button>
|
|
96
131
|
<spectric-button size="small" danger variant="secondary">Override</spectric-button>
|
|
97
132
|
<spectric-button size="small" danger variant="text">Disable</spectric-button>
|
|
98
133
|
<spectric-button size="small" variant="text">test</spectric-button>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ColumnSettings } from "../../components/table";
|
|
1
2
|
|
|
2
3
|
|
|
3
4
|
export const modulations = [
|
|
@@ -15,7 +16,7 @@ export const modulations = [
|
|
|
15
16
|
//pulled from https://www.sigidwiki.com/wiki/Category:Digital signals that don't have a space or -
|
|
16
17
|
export const signals = ["802.11n", "8PSK", "ASCII", "AUTOSPEC", "Aprizesat", "Autocab", "Bluetooth", "CCITT", "CDMA420", "CHIP", "CHU", "COFDMTV", "CompuLert", "Contestia", "Coquelet", "DCF77", "DominoEX", "DominoF", "EIA", "FLEX", "FSK441", "FSQ", "FST4W", "FT4", "FT8", "Hellschreiber", "ISCAT", "JS8", "JT4", "JT65", "JT6M", "JT9", "JTMS", "Kiwi", "Lentus", "LoRa", "MDC1200", "MOBITEX", "MSK144", "MT63", "Milstar", "NML", "NOV", "NPM", "NWC", "Olivia", "OpenSky", "Orbcomm", "PACKET", "PAX", "PI4", "POCSAG", "PSK2K", "Piccolo", "ProVoice", "Q15X25", "ROS", "RTTYM", "ReFLEX", "SIGFOX", "SPREAD", "Serdolik", "SkyOFDM", "THOR", "THROB", "TT2300", "TWINPLEX", "Tetrapol", "VISEL", "VOICE", "WSPR", "WiMAX", "WinDRM"]
|
|
17
18
|
export const filterByColumn = async (field, text) => {
|
|
18
|
-
if(field === "time_seen"){
|
|
19
|
+
if (field === "time_seen") {
|
|
19
20
|
return []
|
|
20
21
|
}
|
|
21
22
|
if (field === "modulations") {
|
|
@@ -30,4 +31,23 @@ export const filterByColumn = async (field, text) => {
|
|
|
30
31
|
return values
|
|
31
32
|
}
|
|
32
33
|
return values.filter(v => v.includes(text))
|
|
33
|
-
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type TestData = {
|
|
37
|
+
name: string
|
|
38
|
+
company: string
|
|
39
|
+
contact: string
|
|
40
|
+
location: {
|
|
41
|
+
country: string,
|
|
42
|
+
state: string
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export const tabledata: TestData[] = [
|
|
46
|
+
{ name: "Sean", company: "Spectric Labs", "contact": "123-4567", location: { "country": "US", state: "VA" } },
|
|
47
|
+
{ name: "Kipp", company: "Spectric Labs", "contact": "123-4567", location: { "country": "UK", state: "N/A" } },
|
|
48
|
+
{ name: "Adam", company: "Spectric Labs", "contact": "123-4567", location: { "country": "US", state: "VA" } },
|
|
49
|
+
{ name: "Chris", company: "Spectric Labs", "contact": "123-4567", location: { "country": "US", state: "VA" } },
|
|
50
|
+
{ name: "Michael", company: "Spectric Labs", "contact": "123-4567", location: { "country": "US", state: "VA" } },
|
|
51
|
+
{ name: "Matt", company: "Spectric Labs", "contact": "123-4567", location: { "country": "US", state: "VA" } },
|
|
52
|
+
{ name: "Grant", company: "Spectric Labs", "contact": "123-4567", location: { "country": "US", state: "VA" } },]
|
|
53
|
+
export const tablecolumns: ColumnSettings<TestData>[] = [{ "title": "Company", key: "company" }, { "title": "Name", key: "name" }, { "title": "Contact", key: "contact" }, { "title": "Country", key: "location.country", filterable: true }]
|
|
@@ -1,27 +1,15 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/web-components";
|
|
2
2
|
|
|
3
|
-
import { PaginationChangeProps, type TableProps as Props } from "../components/";
|
|
3
|
+
import { ColumnSettings, PaginationChangeProps, type TableProps as Props } from "../components/";
|
|
4
4
|
import { html } from "lit";
|
|
5
5
|
import '../components';
|
|
6
6
|
import { ifDefined } from "lit/directives/if-defined.js";
|
|
7
7
|
import { useArgs } from "@storybook/client-api";
|
|
8
8
|
import { FilterEvent } from "../components/table/cell";
|
|
9
|
+
import { tablecolumns, tabledata } from "./fixtures/data";
|
|
9
10
|
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
company: string
|
|
13
|
-
contact: string
|
|
14
|
-
country: string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const data: TestData[] = [
|
|
18
|
-
{ name: "Sean", company: "Spectric Labs", "contact": "123-4567", "country": "US" },
|
|
19
|
-
{ name: "Kipp", company: "Spectric Labs", "contact": "123-4567", "country": "UK" },
|
|
20
|
-
{ name: "Adam", company: "Spectric Labs", "contact": "123-4567", "country": "US" },
|
|
21
|
-
{ name: "Chris", company: "Spectric Labs", "contact": "123-4567", "country": "US" },
|
|
22
|
-
{ name: "Michael", company: "Spectric Labs", "contact": "123-4567", "country": "US" },
|
|
23
|
-
{ name: "Matt", company: "Spectric Labs", "contact": "123-4567", "country": "US" },
|
|
24
|
-
{ name: "Grant", company: "Spectric Labs", "contact": "123-4567", "country": "UK" },]
|
|
11
|
+
const data = tabledata
|
|
12
|
+
const columns = tablecolumns
|
|
25
13
|
const meta = {
|
|
26
14
|
title: "UI/Table",
|
|
27
15
|
tags: ["autodocs"],
|
|
@@ -34,6 +22,7 @@ const meta = {
|
|
|
34
22
|
.pagination=${args.pagination}
|
|
35
23
|
.columns=${args.columns}
|
|
36
24
|
.data=${!args.pagination ? data : data.slice((args.pagination.page - 1) * args.pagination.pageSize, (args.pagination.page) * args.pagination.pageSize)}
|
|
25
|
+
select=${ifDefined(args.select)}
|
|
37
26
|
@filter=${(e: CustomEvent<FilterEvent<any>>) => {
|
|
38
27
|
alert(`filter ${e.detail.include ? "for" : "out"} event value ${e.detail.value}`)
|
|
39
28
|
}}
|
|
@@ -51,15 +40,15 @@ const meta = {
|
|
|
51
40
|
pagination: {
|
|
52
41
|
page: 1,
|
|
53
42
|
pageSize: 3,
|
|
54
|
-
size: "
|
|
43
|
+
size: "xsmall",
|
|
55
44
|
totalItems: data.length,
|
|
56
45
|
},
|
|
57
|
-
columns:
|
|
46
|
+
columns: columns
|
|
58
47
|
},
|
|
59
|
-
} satisfies Meta<Props<
|
|
48
|
+
} satisfies Meta<Props<typeof tabledata[0]>>;
|
|
60
49
|
|
|
61
50
|
export default meta;
|
|
62
|
-
type Story = StoryObj<Props<
|
|
51
|
+
type Story = StoryObj<Props<typeof tabledata[0]>>;
|
|
63
52
|
|
|
64
53
|
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
|
|
65
54
|
export const Basic: Story = {
|
|
@@ -67,8 +56,27 @@ export const Basic: Story = {
|
|
|
67
56
|
pagination: {
|
|
68
57
|
page: 1,
|
|
69
58
|
pageSize: 3,
|
|
70
|
-
size: "
|
|
59
|
+
size: "xsmall",
|
|
71
60
|
totalItems: data.length,
|
|
72
61
|
}
|
|
73
62
|
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
|
|
66
|
+
export const NoPagination: Story = {
|
|
67
|
+
args: {
|
|
68
|
+
pagination: undefined
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const MiltiSelect: Story = {
|
|
73
|
+
args: {
|
|
74
|
+
select: "multi"
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const SingleSelect: Story = {
|
|
79
|
+
args: {
|
|
80
|
+
select: "single"
|
|
81
|
+
},
|
|
74
82
|
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/web-components";
|
|
2
|
+
|
|
3
|
+
import { TooltipPostions, type TooltipProps as Props } from "../components/";
|
|
4
|
+
import { html } from "lit";
|
|
5
|
+
import "../components";
|
|
6
|
+
import { useArgs } from "@storybook/client-api";
|
|
7
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
8
|
+
let positions = Object.values(TooltipPostions);
|
|
9
|
+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories
|
|
10
|
+
const meta = {
|
|
11
|
+
title: "UI/Tooltip",
|
|
12
|
+
tags: ["autodocs"],
|
|
13
|
+
component: "spectric-tooltip",
|
|
14
|
+
render: (args) => {
|
|
15
|
+
const [_, updateArgs] = useArgs();
|
|
16
|
+
|
|
17
|
+
return html`
|
|
18
|
+
${positions.map((p) => {
|
|
19
|
+
return html` <span>
|
|
20
|
+
<spectric-tooltip
|
|
21
|
+
position=${p}
|
|
22
|
+
text=${args.text || p}
|
|
23
|
+
delay=${args.delay}
|
|
24
|
+
animationDuration=${ifDefined(args.animationDuration)}
|
|
25
|
+
>
|
|
26
|
+
</spectric-tooltip>
|
|
27
|
+
${p}
|
|
28
|
+
</span>
|
|
29
|
+
|
|
30
|
+
`;
|
|
31
|
+
})}
|
|
32
|
+
`;
|
|
33
|
+
},
|
|
34
|
+
argTypes: {},
|
|
35
|
+
args: {
|
|
36
|
+
animationDuration: 500,
|
|
37
|
+
delay: 100
|
|
38
|
+
},
|
|
39
|
+
} satisfies Meta<Props>;
|
|
40
|
+
|
|
41
|
+
export default meta;
|
|
42
|
+
type Story = StoryObj<Props>;
|
|
43
|
+
|
|
44
|
+
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
|
|
45
|
+
export const PositionTop: Story = {
|
|
46
|
+
args: {
|
|
47
|
+
position: "top",
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
|
|
52
|
+
export const PositionLeft: Story = {
|
|
53
|
+
args: {
|
|
54
|
+
position: "left",
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const PositionRight: Story = {
|
|
59
|
+
args: {
|
|
60
|
+
position: "right",
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const PositionBottom: Story = {
|
|
65
|
+
args: {
|
|
66
|
+
position: "bottom",
|
|
67
|
+
},
|
|
68
|
+
};
|