@spectric/ui 0.0.4

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.
Files changed (88) hide show
  1. package/.gitlab-ci.yml +28 -0
  2. package/.nvmrc +1 -0
  3. package/.storybook/analyze.sh +4 -0
  4. package/.storybook/main.ts +55 -0
  5. package/.storybook/preview.ts +42 -0
  6. package/.vscode/extensions.json +5 -0
  7. package/.vscode/settings.json +41 -0
  8. package/README.MD +50 -0
  9. package/html-include.png +0 -0
  10. package/package.json +33 -0
  11. package/src/classes/BitArray.ts +48 -0
  12. package/src/classes/DisposibleElement.ts +108 -0
  13. package/src/components/Banner.ts +102 -0
  14. package/src/components/Bitdisplay.ts +383 -0
  15. package/src/components/Button.ts +121 -0
  16. package/src/components/Header.ts +125 -0
  17. package/src/components/Page.ts +157 -0
  18. package/src/components/Panel.ts +56 -0
  19. package/src/components/ThemeProvider.ts +251 -0
  20. package/src/components/button.css.ts +160 -0
  21. package/src/components/configurations/classifications.ts +194 -0
  22. package/src/components/dialog/dialog.css.ts +50 -0
  23. package/src/components/dialog/dialog.ts +163 -0
  24. package/src/components/dialog/index.ts +1 -0
  25. package/src/components/header.css.ts +38 -0
  26. package/src/components/index.ts +10 -0
  27. package/src/components/input.css +75 -0
  28. package/src/components/input.ts +312 -0
  29. package/src/components/page.css.ts +158 -0
  30. package/src/components/panel.css.ts +44 -0
  31. package/src/components/query_bar/QueryBar.css +48 -0
  32. package/src/components/query_bar/QueryBar.ts +378 -0
  33. package/src/components/query_bar/index.ts +2 -0
  34. package/src/components/query_bar/querylanguage/kuery/ast/_generated_/kuery.js +3186 -0
  35. package/src/components/query_bar/querylanguage/kuery/ast/ast.ts +113 -0
  36. package/src/components/query_bar/querylanguage/kuery/ast/index.ts +31 -0
  37. package/src/components/query_bar/querylanguage/kuery/ast/kuery.peg +417 -0
  38. package/src/components/query_bar/querylanguage/kuery/functions/and.ts +55 -0
  39. package/src/components/query_bar/querylanguage/kuery/functions/exists.ts +62 -0
  40. package/src/components/query_bar/querylanguage/kuery/functions/index.ts +47 -0
  41. package/src/components/query_bar/querylanguage/kuery/functions/is.ts +211 -0
  42. package/src/components/query_bar/querylanguage/kuery/functions/nested.ts +63 -0
  43. package/src/components/query_bar/querylanguage/kuery/functions/not.ts +53 -0
  44. package/src/components/query_bar/querylanguage/kuery/functions/or.ts +56 -0
  45. package/src/components/query_bar/querylanguage/kuery/functions/range.ts +163 -0
  46. package/src/components/query_bar/querylanguage/kuery/functions/utils/get_fields.ts +49 -0
  47. package/src/components/query_bar/querylanguage/kuery/functions/utils/get_full_field_name_node.ts +87 -0
  48. package/src/components/query_bar/querylanguage/kuery/index.ts +38 -0
  49. package/src/components/query_bar/querylanguage/kuery/kuery_syntax_error.ts +76 -0
  50. package/src/components/query_bar/querylanguage/kuery/node_types/function.ts +75 -0
  51. package/src/components/query_bar/querylanguage/kuery/node_types/index.ts +46 -0
  52. package/src/components/query_bar/querylanguage/kuery/node_types/literal.ts +42 -0
  53. package/src/components/query_bar/querylanguage/kuery/node_types/named_arg.ts +47 -0
  54. package/src/components/query_bar/querylanguage/kuery/node_types/types.ts +108 -0
  55. package/src/components/query_bar/querylanguage/kuery/node_types/wildcard.ts +80 -0
  56. package/src/components/query_bar/querylanguage/kuery/types.ts +52 -0
  57. package/src/components/query_bar/querylanguage/outputTypes/toCQL.ts +122 -0
  58. package/src/components/query_bar/querylanguage/outputTypes/toMongo.ts +103 -0
  59. package/src/components/query_bar/querylanguage/utils.ts +35 -0
  60. package/src/components/query_bar/types.ts +59 -0
  61. package/src/components/splitview/index.ts +1 -0
  62. package/src/components/splitview/splitview.css.ts +66 -0
  63. package/src/components/splitview/splitview.ts +183 -0
  64. package/src/components/types.ts +35 -0
  65. package/src/index.ts +1 -0
  66. package/src/stories/Banner.stories.ts +46 -0
  67. package/src/stories/BitDisplay.stories.ts +68 -0
  68. package/src/stories/Button.stories.ts +138 -0
  69. package/src/stories/Header.stories.ts +55 -0
  70. package/src/stories/Page.stories.ts +108 -0
  71. package/src/stories/QueryBar.stories.ts +63 -0
  72. package/src/stories/Splitview.stories.ts +52 -0
  73. package/src/stories/fixtures/Bits.ts +15 -0
  74. package/src/stories/fixtures/ExampleContent.ts +102 -0
  75. package/src/stories/fixtures/data.ts +30 -0
  76. package/src/stories/fixtures/lorumipsum.ts +19 -0
  77. package/src/stories/input.stories.ts +77 -0
  78. package/src/stories/tsconfig.json +35 -0
  79. package/src/utils/debounce.ts +18 -0
  80. package/src/utils/spread.ts +71 -0
  81. package/src/vite-env.d.ts +1 -0
  82. package/test/__init__.py +9 -0
  83. package/test/elastic.py +9 -0
  84. package/test/interface.py +16 -0
  85. package/tsconfig.json +29 -0
  86. package/vite.config.js +34 -0
  87. package/vue-example.png +0 -0
  88. package/vue-include.png +0 -0
@@ -0,0 +1,383 @@
1
+ import { css, html, PropertyValues } from 'lit';
2
+
3
+
4
+ import { customElement, property, queryAsync } from 'lit/decorators.js';
5
+ import { createRef, ref, Ref } from 'lit/directives/ref.js';
6
+ import { BitArray } from "../classes/BitArray"
7
+ import { DisposableElement, IDisposable } from '../classes/DisposibleElement';
8
+ import { debounceAnimation } from '../utils/debounce';
9
+ import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from './types';
10
+
11
+ export interface BitDisplayProps {
12
+ /** Array buffer to display */
13
+ arrayBuffer: ArrayBuffer;
14
+ /** Bits per line */
15
+ frameWidth: number;
16
+ /** How many pixels per bit */
17
+ scale: number;
18
+ /** Width of the display canvas */
19
+ width: number;
20
+ /** Height of the display canvas */
21
+ height: number;
22
+
23
+ }
24
+ type Position = {
25
+ x: number;
26
+ y: number;
27
+ }
28
+ export type BitDisplayMouseEvent = {
29
+ position: Position,
30
+ nativeEvent: MouseEvent
31
+ bitIndex: number
32
+ }
33
+ const events = ["mousemove", "click", "dblclick", "mousedown", "mouseup", "contextmenu"] as const
34
+ type BitEventHandler = (event: CustomEvent<BitDisplayMouseEvent>) => void
35
+ type AllEvents = typeof events
36
+
37
+ export interface BitDisplayEventMap extends Record<`bit${Capitalize<AllEvents[number]>}`, BitEventHandler> {
38
+ }
39
+
40
+
41
+ const DEFAULT_SIZE = { width: 200, height: 200 }
42
+ const SCROLLBAR_SIZE = { width: 10, height: 10 }
43
+ /**
44
+ * @fires bitMousemove - emits BitDisplayMouseEvent on mousemove over the canvas
45
+ * @fires bitClick - emits BitDisplayMouseEvent on mouse click on the canvas
46
+ * @fires bitDblclick - emits BitDisplayMouseEvent on mouse double click on the canvas
47
+ * @fires bitMousedown - emits BitDisplayMouseEvent on mouse down onthe canvas
48
+ * @fires bitMouseup - emits BitDisplayMouseEvent on mouse up on the canvas
49
+ * @fires bitContextmenu - emits BitDisplayMouseEvent on mouse right click on the canvas
50
+ */
51
+ @customElement("spectric-bit-display")
52
+ export class BitDisplayCanvas extends DisposableElement implements BitDisplayProps {
53
+ @property({ type: Object, attribute: false })
54
+ arrayBuffer: ArrayBuffer = new ArrayBuffer(0);
55
+ @property({ type: Number })
56
+ frameWidth: number = 100;
57
+ @property({ type: Number })
58
+ scale: number = 1;
59
+ @property({ type: Number })
60
+ width: number = 200;
61
+ @property({ type: Number })
62
+ height: number = 200;
63
+ static styles = css`
64
+ :host{
65
+ position: relative;
66
+ --border-radius: var(--spectric-border-radius,4em);
67
+ --scroll-color: var(--spectric-background-inverse,#393939);
68
+ --background-color: var(--spectric-background, #ffffff);
69
+ }
70
+ #viewport{
71
+ overflow: scroll;
72
+ position: absolute;
73
+ }
74
+ #fakescrolldiv {
75
+ position: relative;
76
+ overflow-x: hidden;
77
+ overflow-y: hidden;
78
+ z-index:-1;
79
+ }
80
+ canvas{
81
+ position: absolute;
82
+ left:0;
83
+ top:0;
84
+ background-color:var(--background-color);
85
+ }
86
+ ::-webkit-scrollbar {
87
+ height: ${SCROLLBAR_SIZE.height}px;
88
+ width: ${SCROLLBAR_SIZE.width}px;
89
+
90
+ }
91
+
92
+ /* Webkit psudo elements don't pick up variables defined by the host */
93
+ ::-webkit-scrollbar-thumb {
94
+ background: var(--spectric-background-inverse,#393939);
95
+ border-radius: var(--spectric-border-radius,4em);
96
+ -webkit-border-radius: var(--spectric-border-radius,4em);
97
+ padding-top: 1px;
98
+ padding-bottom: 1px;
99
+ box-shadow: 0 0 1px var(--spectric-primary,#242424) inset;
100
+ }
101
+ ::-webkit-scrollbar-thumb:hover {
102
+ background: var(--spectric-primary,#009eb3);
103
+ }
104
+ ::-webkit-scrollbar-corner {
105
+ background: var(--spectric-background, #ffffff);
106
+ }
107
+ /* Buttons */
108
+
109
+ ::-webkit-scrollbar-button:single-button {
110
+ background-color: transparent;
111
+ display: block;
112
+ border-style: solid;
113
+ }/* Up */
114
+ ::-webkit-scrollbar-button:single-button:vertical:decrement {
115
+ border-width: 0 5px 5px 5px;
116
+ border-color: var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-background-inverse,#393939) var(--spectric-background, #ffffff);
117
+ }
118
+ ::-webkit-scrollbar-button:single-button:vertical:decrement:hover {
119
+ border-color: var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-primary,#009eb3) var(--spectric-background, #ffffff);
120
+ }
121
+ /* Down */
122
+ ::-webkit-scrollbar-button:single-button:vertical:increment {
123
+ border-width: 5px 5px 0 5px;
124
+ border-color: var(--spectric-background-inverse,#393939) var(--spectric-background, #ffffff) transparent var(--spectric-background, #ffffff);
125
+ }
126
+
127
+ ::-webkit-scrollbar-button:vertical:single-button:increment:hover {
128
+ border-color: var(--spectric-primary,#009eb3) var(--spectric-background, #ffffff) transparent var(--spectric-background, #ffffff);
129
+ }
130
+
131
+ /* Left */
132
+ ::-webkit-scrollbar-button:single-button:horizontal:decrement {
133
+ border-width: 5px 5px 5px 0;
134
+ border-color:var(--spectric-background, #ffffff) var(--spectric-background-inverse,#393939) var(--spectric-background, #ffffff) var(--spectric-background, #ffffff);
135
+
136
+ }
137
+
138
+ ::-webkit-scrollbar-button:single-button:horizontal:decrement:hover {
139
+ border-width: 5px 5px 5px 0;
140
+ border-color:var(--spectric-background, #ffffff) var(--spectric-primary,#009eb3) var(--spectric-background, #ffffff) var(--spectric-background, #ffffff);
141
+
142
+ }
143
+
144
+
145
+
146
+ /* Right */
147
+ ::-webkit-scrollbar-button:single-button:horizontal:increment {
148
+ border-width: 5px 0 5px 5px;
149
+ border-color:var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-background-inverse,#393939);
150
+
151
+ }
152
+
153
+ ::-webkit-scrollbar-button:single-button:horizontal:increment:hover {
154
+ border-width: 5px 0 5px 5px;
155
+ border-color:var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-primary,#009eb3);
156
+
157
+ }
158
+
159
+ `
160
+ private state: { scale?: number } = {};
161
+ private yStart: number = 0;
162
+ private xStart: number = 0;
163
+ @queryAsync("canvas")
164
+ private _canvas!: Promise<HTMLCanvasElement>
165
+ private refs: {
166
+ viewport: Ref<HTMLDivElement>,
167
+ canvas: Ref<HTMLCanvasElement>, scrollDiv: Ref<HTMLDivElement>
168
+ } = {
169
+ viewport: createRef(),
170
+ canvas: createRef(),
171
+ scrollDiv: createRef()
172
+ };
173
+ private _bitArray?: any;
174
+
175
+ private resizeObserver: ResizeObserver & IDisposable;
176
+ private color: string = "#000000";
177
+ constructor() {
178
+ super();
179
+ let observer = new ResizeObserver(this.onResize) as any
180
+ observer.dispose = () => {
181
+ this.resizeObserver.disconnect()
182
+ }
183
+ this.resizeObserver = observer
184
+ this.addDisposableListener(document.body, "theme-change", this.onThemeChange)
185
+
186
+ var lastPosition: Partial<Record<AllEvents[number], number>> = {}
187
+ events.forEach(eventName => {
188
+ this.addDisposableListener(this._canvas, eventName, debounceAnimation(async (e: MouseEvent) => {
189
+ e.stopImmediatePropagation()
190
+ e.stopPropagation()
191
+ e.preventDefault()
192
+ var canvas = await (this._canvas)
193
+ let rect = canvas.getBoundingClientRect()
194
+ let position = {
195
+ x: Math.floor(Math.abs(e.clientX - rect.left)),
196
+ y: Math.floor(Math.abs(e.clientY - rect.top))
197
+ };
198
+ let bitIndex = this.canvasPositionToBit(position)
199
+ //If the bit index didn't change we don't need to fire an event, this can happen when the scale is more than 1px
200
+ if (eventName === "mousemove" && lastPosition[eventName] == bitIndex) {
201
+ return
202
+ }
203
+ lastPosition[eventName] = bitIndex
204
+ let bitEventName = "bit" + String(eventName).charAt(0).toUpperCase() + String(eventName).slice(1)
205
+ if (bitIndex != -1) {
206
+ let event = new CustomEvent<BitDisplayMouseEvent>(bitEventName, {
207
+ detail: { bitIndex, position, nativeEvent: e }
208
+ })
209
+ this.dispatchEvent(event)
210
+ }
211
+ }))
212
+ })
213
+
214
+ }
215
+ private onThemeChange = () => {
216
+ let cssStyle = getComputedStyle(this);
217
+ if (this.color != cssStyle.color) {
218
+ this.color = cssStyle.color
219
+ this.paint()
220
+ }
221
+ }
222
+ connectedCallback(): void {
223
+ this.onResize()
224
+ super.connectedCallback()
225
+ this.registerDisposable(this.resizeObserver)
226
+ this.resizeObserver.observe(this)
227
+ }
228
+
229
+
230
+ protected updated(changedProperties: PropertyValues): void {
231
+ if (changedProperties.has("arrayBuffer")) {
232
+ if (this.arrayBuffer) {
233
+ this._bitArray = new BitArray(this.arrayBuffer);
234
+ }
235
+ }
236
+ const repaintProps = ["arrayBuffer", "scale", "frameWidth", "width", "height"]
237
+ for (const prop of repaintProps) {
238
+ if (changedProperties.has(prop)) {
239
+ this.paint();
240
+ return
241
+ }
242
+ }
243
+ }
244
+
245
+
246
+ private onResize = () => {
247
+ this.calculateViewport();
248
+ }
249
+ canvasPositionToBit(position: { x: number, y: number }) {
250
+ let x = Math.floor(position.x / this.scale)
251
+ let y = Math.floor(position.y / this.scale)
252
+ if (x > this.frameWidth - 1) {
253
+ return -1
254
+ }
255
+ let startBit = this.yStart * this.frameWidth + this.xStart
256
+ return startBit + (y * this.frameWidth + x)
257
+ }
258
+ paint() {
259
+ if (!this.refs.canvas.value || !this._bitArray) {
260
+ return
261
+ }
262
+ const { frameWidth, _bitArray: bitArray } = this;
263
+ if (frameWidth <= 0) {
264
+ return
265
+ }
266
+ this.calculateViewport()
267
+ const { width = DEFAULT_SIZE.width, height = DEFAULT_SIZE.height } = this;
268
+ const scale = this.getPxPerBit()
269
+ const context = this.refs.canvas.value.getContext("2d");
270
+ if (!context) {
271
+ return
272
+ }
273
+ if (this.state.scale != scale) {
274
+ context.reset()
275
+ context.scale(scale, scale);
276
+ }
277
+ let cssStyle = getComputedStyle(this);
278
+ context.fillStyle = cssStyle.color
279
+ context.clearRect(0, 0, width, height);
280
+ let y = 0;
281
+
282
+ for (
283
+ let i = this.yStart * frameWidth + this.xStart, len = bitArray.length;
284
+ i < len;
285
+ i++
286
+ ) {
287
+ let x = (i % frameWidth) - this.xStart;
288
+ if (x < 0) {
289
+ continue; //Less than 0 we are off screen
290
+ }
291
+ if (Math.floor(x * scale) > width) {
292
+ y++;
293
+ i = y * frameWidth + this.yStart * frameWidth + this.xStart - 1;
294
+ continue; //Don't bother going if it is off screen
295
+ }
296
+ if (Math.floor(y * scale) > height) {
297
+ break; //Don't bother going if it is off screen
298
+ }
299
+ if (bitArray.getBit(i) === 1) {
300
+ context.fillRect(x, y, 1, 1);
301
+ }
302
+ if ((i + 1) % frameWidth === 0 && i >= frameWidth - 1) {
303
+ y++;
304
+ }
305
+ }
306
+ }
307
+ private handleScroll = () => {
308
+ if (!this.refs.viewport.value) {
309
+ return
310
+ }
311
+ const scale = this.getPxPerBit()
312
+ this.yStart = this.refs.viewport.value.scrollTop
313
+ ? Math.floor(this.refs.viewport.value.scrollTop / scale) + 1
314
+ : 0;
315
+ this.xStart = this.refs.viewport.value.scrollLeft
316
+ ? Math.floor(this.refs.viewport.value.scrollLeft / scale) + 1
317
+ : 0;
318
+ this.paint();
319
+ }
320
+
321
+ getPxPerBit() {
322
+ return this.scale > 0 ? this.scale : 1;
323
+ }
324
+ calculateViewport() {
325
+ const { frameWidth, _bitArray: bitArray } = this;
326
+ if (this.refs.scrollDiv.value) {
327
+ var pxPerBit = this.getPxPerBit();
328
+ const height = (bitArray.length / frameWidth) * pxPerBit;
329
+ const width = frameWidth * pxPerBit;
330
+ const div = this.refs.scrollDiv.value;
331
+ div.style.width = width + "px";
332
+ div.style.height = height + "px"
333
+ }
334
+ }
335
+ protected render(): unknown {
336
+ //return html`<div>here</div>`
337
+ const { height = DEFAULT_SIZE.height, width = DEFAULT_SIZE.width } = this
338
+ return html`
339
+ <div
340
+ id="viewport"
341
+ ${ref(this.refs.viewport)}
342
+ @scroll=${this.handleScroll}
343
+ style=${`width:${width}px;height:${height}px;overflow:auto;position:relative`}
344
+ >
345
+ <div
346
+ id="fakescrolldiv"
347
+ ${ref(this.refs.scrollDiv)}
348
+ >
349
+ </div>
350
+ </div>
351
+ <canvas
352
+ ${ref(this.refs.canvas)}
353
+ width=${width - SCROLLBAR_SIZE.width}
354
+ height=${height - SCROLLBAR_SIZE.height}
355
+ ></canvas>
356
+ `
357
+
358
+ }
359
+ }
360
+
361
+ declare global {
362
+ interface HTMLElementTagNameMap {
363
+ "spectric-bit-display": HTMLElementTagWithEvents<BitDisplayCanvas, BitDisplayEventMap>
364
+ }
365
+ namespace JSX {
366
+ interface IntrinsicElements {
367
+ /**
368
+ * {@link BitDisplayCanvas}
369
+ */
370
+ "spectric-bit-display": ReactElementWithPropsAndEvents<BitDisplayCanvas, BitDisplayProps, BitDisplayEventMap>;
371
+ }
372
+ }
373
+ namespace React {
374
+ namespace JSX {
375
+ interface IntrinsicElements {
376
+ /**
377
+ * {@link BitDisplayCanvas}
378
+ */
379
+ "spectric-bit-display": ReactElementWithPropsAndEvents<BitDisplayCanvas, BitDisplayProps, BitDisplayEventMap>;
380
+ }
381
+ }
382
+ }
383
+ }
@@ -0,0 +1,121 @@
1
+ import { CSSResultGroup, html, LitElement } from 'lit';
2
+ import { styleMap } from 'lit/directives/style-map.js';
3
+
4
+ import style from './button.css';
5
+ import { customElement, property } from 'lit/decorators.js';
6
+ import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from './types';
7
+
8
+ export enum ButtonSizes {
9
+ large = "large",
10
+ medium = "medium",
11
+ small = "small",
12
+ }
13
+ type ButtonSizesTypes = `${ButtonSizes}`
14
+ export enum ButtonVariants {
15
+ primary = "primary",
16
+ secondary = "secondary",
17
+ text = "text"
18
+ }
19
+ type ButtonVariantsTypes = `${ButtonVariants}`
20
+ export interface ButtonProps {
21
+ /** Is this the principal call to action on the page? */
22
+ variant: ButtonVariantsTypes;
23
+ /** What background color to use */
24
+ backgroundColor?: string;
25
+ /** How large should the button be? */
26
+ size: ButtonSizesTypes;
27
+ label?: string,
28
+ /* should the button be disabled*/
29
+ disabled: boolean;
30
+ danger?: boolean;
31
+ }
32
+ const MODES = {
33
+ "primary": 'spectric-button--primary',
34
+ "secondary": 'spectric-button--secondary',
35
+ "text": 'spectric-button--text',
36
+ }
37
+
38
+ @customElement('spectric-button')
39
+ export class SpectricButton extends LitElement implements ButtonProps {
40
+
41
+ static styles?: CSSResultGroup | undefined = style;
42
+ @property({ type: String, reflect: true })
43
+ variant: 'primary' | 'secondary' | 'text' = "primary";
44
+ @property({ type: Boolean, reflect: true })
45
+ disabled: boolean = false;
46
+ @property({ type: String, reflect: true })
47
+ backgroundColor?: string | undefined;
48
+ @property({ type: String, reflect: true })
49
+ size: 'small' | 'medium' | 'large' = "large";
50
+ @property({ type: String, reflect: true })
51
+ label?: string = "";
52
+ @property({ type: Boolean, reflect: true })
53
+ danger = false;
54
+ connectedCallback(): void {
55
+ super.connectedCallback()
56
+ this.addEventListener("click", this._onClick)
57
+ }
58
+ disconnectedCallback(): void {
59
+ super.disconnectedCallback()
60
+ this.removeEventListener("click", this._onClick)
61
+ }
62
+ private _onClick = (e: MouseEvent) => {
63
+ if (e instanceof CustomEvent) {
64
+ return
65
+ }
66
+ e.preventDefault()
67
+ e.stopImmediatePropagation()
68
+ e.stopPropagation()
69
+ const options: CustomEventInit = {
70
+ bubbles: true,
71
+ composed: true,
72
+ detail: e
73
+ };
74
+ this.dispatchEvent(new CustomEvent<MouseEvent>('click', options));
75
+ }
76
+
77
+ protected render(): unknown {
78
+ const mode = MODES[this.variant] || 'spectric-button--primary';
79
+ return html`
80
+ <button
81
+ type="button"
82
+ ?disabled=${this.disabled}
83
+ class=${['spectric-button', `spectric-button-danger--${this.danger || false}`, `spectric-button--${this.size || 'medium'}`, mode].join(' ')}
84
+ style=${styleMap({ backgroundColor: this.backgroundColor })}
85
+ >
86
+ <span class="animation"></span>
87
+ <slot>${this.label}</slot>
88
+ </button>
89
+ `;
90
+ }
91
+ }
92
+
93
+ export interface ButtonEventMap {
94
+ //"aaa":(event:CustomEvent<ButtonProps>)=>void
95
+ "click": (event: CustomEvent<MouseEvent>) => void;
96
+ }
97
+
98
+ declare global {
99
+ interface HTMLElementTagNameMap {
100
+ "spectric-button": HTMLElementTagWithEvents<SpectricButton, ButtonEventMap>
101
+
102
+ }
103
+ namespace JSX {
104
+ interface IntrinsicElements {
105
+ /**
106
+ * {@link SpectricButton}
107
+ */
108
+ "spectric-button": ReactElementWithPropsAndEvents<SpectricButton, ButtonProps, ButtonEventMap>;
109
+ }
110
+ }
111
+ namespace React {
112
+ namespace JSX {
113
+ interface IntrinsicElements {
114
+ /**
115
+ * {@link SpectricButton}
116
+ */
117
+ "spectric-button": ReactElementWithPropsAndEvents<SpectricButton, ButtonProps, ButtonEventMap>;
118
+ }
119
+ }
120
+ }
121
+ }
@@ -0,0 +1,125 @@
1
+ import { html, LitElement, TemplateResult } from 'lit';
2
+
3
+ import '.';
4
+ import { customElement, property } from 'lit/decorators.js';
5
+ import styles from './header.css';
6
+ import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from './types';
7
+
8
+
9
+ /**
10
+ * Properties defining
11
+ */
12
+ export interface HeaderProps {
13
+ username: string;
14
+ /**
15
+ * Shows the login Button
16
+ */
17
+ showLoginButton?: boolean
18
+ /**
19
+ * Shows the create account Button when not logged in
20
+ */
21
+ showCreateAccount?: boolean
22
+ }
23
+ export interface HeaderSlots {
24
+ /** Main name of the application */
25
+ name?: string | Node | TemplateResult
26
+ /** Slot to the left of the title typically used for app icons, and/or dropdown navigation menus.*/
27
+ branding?: string | Node | TemplateResult
28
+ /** Slot in the center of the header.*/
29
+ center?: string | Node | TemplateResult
30
+ /** slot right of login/out buttons*/
31
+ end?: string | Node | TemplateResult
32
+ }
33
+
34
+ export interface HeaderEventMap {
35
+ "login": (event: CustomEvent<void>) => void;
36
+ "logout": (event: CustomEvent<void>) => void;
37
+ "createAccount": (event: CustomEvent<void>) => void
38
+ }
39
+
40
+ /**
41
+ * @slot name - Main name of the application
42
+ * @slot branding - Slot to the left of the title typically used for app icons, and/or dropdown navigation menus.
43
+ * @slot center - Slot in the center of the header.
44
+ * @slot end - slot right of login/out buttons
45
+ */
46
+ @customElement("spectric-header")
47
+ export class Header extends LitElement implements HeaderProps {
48
+ static styles = styles
49
+ @property({ type: Boolean, reflect: true }) showCreateAccount: boolean = false;
50
+ @property({ type: Boolean, reflect: true }) showLoginButton: boolean = false;
51
+ @property({ type: String, reflect: true }) username: string = "";
52
+ onLogout = () => {
53
+ const options = {
54
+ bubbles: true,
55
+ composed: true,
56
+ };
57
+ this.dispatchEvent(new CustomEvent('logout', options));
58
+
59
+ }
60
+ onLogin = () => {
61
+ const options = {
62
+ bubbles: true,
63
+ composed: true,
64
+ };
65
+ this.dispatchEvent(new CustomEvent('login', options));
66
+ }
67
+ onCreateAccount = () => {
68
+ const options = {
69
+ bubbles: true,
70
+ composed: true,
71
+ };
72
+ this.dispatchEvent(new CustomEvent('createAccount', options));
73
+ }
74
+ protected render() {
75
+ return html`
76
+ <header>
77
+ <div class="spectric-header">
78
+ <div style="flex-grow:1;">
79
+ <slot name="branding"></slot>
80
+ <h1><slot name="name"></slot></h1>
81
+ <slot name="center"></slot>
82
+ </div>
83
+ ${this.showLoginButton !== false ? html`
84
+ <div>
85
+ ${(this.username && this.username !== "")
86
+ ? html`<spectric-button variant="secondary" size="small" @click=${this.onLogout}>Log out</spectric-button>`
87
+ : html`
88
+ ${this.showCreateAccount !== false ? html`<spectric-button variant="text" size="small" @click=${this.onCreateAccount}>Sign up</spectric-button>` : null}
89
+ <spectric-button variant="primary" size="small" @click=${this.onLogin}>Log in</spectric-button>`
90
+ }
91
+
92
+
93
+ </div>`: null}
94
+ <slot name="end"></slot>
95
+ </div>
96
+ </header>
97
+ `
98
+ }
99
+ }
100
+
101
+
102
+
103
+ declare global {
104
+ interface HTMLElementTagNameMap {
105
+ "spectric-header": HTMLElementTagWithEvents<Header, HeaderEventMap>
106
+ }
107
+ namespace JSX {
108
+ interface IntrinsicElements {
109
+ /**
110
+ * {@link Header}
111
+ */
112
+ "spectric-header": ReactElementWithPropsAndEvents<Header, HeaderProps, HeaderEventMap>;
113
+ }
114
+ }
115
+ namespace React {
116
+ namespace JSX {
117
+ interface IntrinsicElements {
118
+ /**
119
+ * {@link Header}
120
+ */
121
+ "spectric-header": ReactElementWithPropsAndEvents<Header, HeaderProps, HeaderEventMap>;
122
+ }
123
+ }
124
+ }
125
+ }