@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.
- package/.gitlab-ci.yml +28 -0
- package/.nvmrc +1 -0
- package/.storybook/analyze.sh +4 -0
- package/.storybook/main.ts +55 -0
- package/.storybook/preview.ts +42 -0
- package/.vscode/extensions.json +5 -0
- package/.vscode/settings.json +41 -0
- package/README.MD +50 -0
- package/html-include.png +0 -0
- package/package.json +33 -0
- package/src/classes/BitArray.ts +48 -0
- package/src/classes/DisposibleElement.ts +108 -0
- package/src/components/Banner.ts +102 -0
- package/src/components/Bitdisplay.ts +383 -0
- package/src/components/Button.ts +121 -0
- package/src/components/Header.ts +125 -0
- package/src/components/Page.ts +157 -0
- package/src/components/Panel.ts +56 -0
- package/src/components/ThemeProvider.ts +251 -0
- package/src/components/button.css.ts +160 -0
- package/src/components/configurations/classifications.ts +194 -0
- package/src/components/dialog/dialog.css.ts +50 -0
- package/src/components/dialog/dialog.ts +163 -0
- package/src/components/dialog/index.ts +1 -0
- package/src/components/header.css.ts +38 -0
- package/src/components/index.ts +10 -0
- package/src/components/input.css +75 -0
- package/src/components/input.ts +312 -0
- package/src/components/page.css.ts +158 -0
- package/src/components/panel.css.ts +44 -0
- package/src/components/query_bar/QueryBar.css +48 -0
- package/src/components/query_bar/QueryBar.ts +378 -0
- package/src/components/query_bar/index.ts +2 -0
- package/src/components/query_bar/querylanguage/kuery/ast/_generated_/kuery.js +3186 -0
- package/src/components/query_bar/querylanguage/kuery/ast/ast.ts +113 -0
- package/src/components/query_bar/querylanguage/kuery/ast/index.ts +31 -0
- package/src/components/query_bar/querylanguage/kuery/ast/kuery.peg +417 -0
- package/src/components/query_bar/querylanguage/kuery/functions/and.ts +55 -0
- package/src/components/query_bar/querylanguage/kuery/functions/exists.ts +62 -0
- package/src/components/query_bar/querylanguage/kuery/functions/index.ts +47 -0
- package/src/components/query_bar/querylanguage/kuery/functions/is.ts +211 -0
- package/src/components/query_bar/querylanguage/kuery/functions/nested.ts +63 -0
- package/src/components/query_bar/querylanguage/kuery/functions/not.ts +53 -0
- package/src/components/query_bar/querylanguage/kuery/functions/or.ts +56 -0
- package/src/components/query_bar/querylanguage/kuery/functions/range.ts +163 -0
- package/src/components/query_bar/querylanguage/kuery/functions/utils/get_fields.ts +49 -0
- package/src/components/query_bar/querylanguage/kuery/functions/utils/get_full_field_name_node.ts +87 -0
- package/src/components/query_bar/querylanguage/kuery/index.ts +38 -0
- package/src/components/query_bar/querylanguage/kuery/kuery_syntax_error.ts +76 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/function.ts +75 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/index.ts +46 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/literal.ts +42 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/named_arg.ts +47 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/types.ts +108 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/wildcard.ts +80 -0
- package/src/components/query_bar/querylanguage/kuery/types.ts +52 -0
- package/src/components/query_bar/querylanguage/outputTypes/toCQL.ts +122 -0
- package/src/components/query_bar/querylanguage/outputTypes/toMongo.ts +103 -0
- package/src/components/query_bar/querylanguage/utils.ts +35 -0
- package/src/components/query_bar/types.ts +59 -0
- package/src/components/splitview/index.ts +1 -0
- package/src/components/splitview/splitview.css.ts +66 -0
- package/src/components/splitview/splitview.ts +183 -0
- package/src/components/types.ts +35 -0
- package/src/index.ts +1 -0
- package/src/stories/Banner.stories.ts +46 -0
- package/src/stories/BitDisplay.stories.ts +68 -0
- package/src/stories/Button.stories.ts +138 -0
- package/src/stories/Header.stories.ts +55 -0
- package/src/stories/Page.stories.ts +108 -0
- package/src/stories/QueryBar.stories.ts +63 -0
- package/src/stories/Splitview.stories.ts +52 -0
- package/src/stories/fixtures/Bits.ts +15 -0
- package/src/stories/fixtures/ExampleContent.ts +102 -0
- package/src/stories/fixtures/data.ts +30 -0
- package/src/stories/fixtures/lorumipsum.ts +19 -0
- package/src/stories/input.stories.ts +77 -0
- package/src/stories/tsconfig.json +35 -0
- package/src/utils/debounce.ts +18 -0
- package/src/utils/spread.ts +71 -0
- package/src/vite-env.d.ts +1 -0
- package/test/__init__.py +9 -0
- package/test/elastic.py +9 -0
- package/test/interface.py +16 -0
- package/tsconfig.json +29 -0
- package/vite.config.js +34 -0
- package/vue-example.png +0 -0
- package/vue-include.png +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { CSSResultGroup, html, LitElement } from 'lit';
|
|
2
|
+
|
|
3
|
+
import { HeaderEventMap, HeaderProps, HeaderSlots } from './Header';
|
|
4
|
+
import { BannerEventMap, BannerProps } from './Banner';
|
|
5
|
+
import "./Banner"
|
|
6
|
+
import styles from './page.css';
|
|
7
|
+
import { customElement } from 'lit/decorators/custom-element.js';
|
|
8
|
+
import { property } from 'lit/decorators/property.js';
|
|
9
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
10
|
+
import { spreadProps } from '../utils/spread';
|
|
11
|
+
import { Classifications, ClassificationVariants } from './configurations/classifications';
|
|
12
|
+
import { ClassificationStyles } from './configurations/classifications';
|
|
13
|
+
import { KnownThemes, ThemeEventMap } from './ThemeProvider';
|
|
14
|
+
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from './types';
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
export interface PageBanners {
|
|
18
|
+
classification?: { type: Classifications, text: string }
|
|
19
|
+
notifications?: BannerProps[]
|
|
20
|
+
}
|
|
21
|
+
export interface PageProps extends HeaderProps {
|
|
22
|
+
theme?: KnownThemes
|
|
23
|
+
showHeader?: boolean
|
|
24
|
+
/** Will control if the top navbar will stay at the top or scroll with the main content */
|
|
25
|
+
headerSticky?: boolean
|
|
26
|
+
classificationLevel?: Classifications
|
|
27
|
+
/** Overrides the default classification banner text */
|
|
28
|
+
classificationText: string
|
|
29
|
+
notifications?: BannerProps[]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PageSlots extends HeaderSlots {
|
|
33
|
+
/** @description Application Main Conent */
|
|
34
|
+
content?: Node | TemplateStringsArray | string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Spectric page is a basic component that will put all content into an area that expands to fill the whole screen. It calculates the size of the banners and headers for you.
|
|
41
|
+
*
|
|
42
|
+
* It exposes css properties to style all the spectric compenents contained within
|
|
43
|
+
*
|
|
44
|
+
* This component does not fire any events directly but sub components do. See HeaderEventMap & ThemeEventMap & BannerEventMap for full list of events
|
|
45
|
+
* @slot - Main content
|
|
46
|
+
* @slot content - Main content
|
|
47
|
+
* @slot name - Main name of the application
|
|
48
|
+
* @slot branding - Slot to the left of the title typically used for app icons, and/or dropdown navigation menus.
|
|
49
|
+
* @slot center - Slot in the center of the header.
|
|
50
|
+
* @slot end - slot right of login/out buttons
|
|
51
|
+
* @cssprop [--primary=#1ea7fd] - primary color
|
|
52
|
+
* @cssprop [--secondary=#1ea7fd] - secondary color
|
|
53
|
+
* @cssprop [--tertiary=#1ea7fd] - tertiary color
|
|
54
|
+
* @cssprop [--disabled=#1ea7fd] - disabled color
|
|
55
|
+
* @cssprop [--text-primary=#1ea7fd] - text colors
|
|
56
|
+
* @cssprop [--text-secondary=#1ea7fd] - text colors
|
|
57
|
+
* @cssprop [--text-on-color=#ffffff] - color of text on color
|
|
58
|
+
* @cssprop [--background=#1ea7fd] - background color
|
|
59
|
+
* @cssprop [--background-inverse=#f4f4f4] - Even Panel colors
|
|
60
|
+
* @cssprop [--border-radius=0.4em] - sets global border radius
|
|
61
|
+
* @see Events {@link SpectricEventsMaps}
|
|
62
|
+
*/
|
|
63
|
+
@customElement("spectric-page")
|
|
64
|
+
export class SpectricPage extends LitElement implements PageProps {
|
|
65
|
+
static styles?: CSSResultGroup | undefined = styles;
|
|
66
|
+
|
|
67
|
+
@property({ type: Boolean, reflect: true }) showHeader: boolean = true;
|
|
68
|
+
@property({ type: Boolean, reflect: true }) headerSticky: boolean = true;
|
|
69
|
+
@property({ type: String, reflect: true }) classificationLevel?: Classifications = ClassificationVariants.None;
|
|
70
|
+
@property({ type: String, reflect: true }) classificationText: string = "";
|
|
71
|
+
@property({ type: Array, reflect: true }) notifications: BannerProps[] = [];
|
|
72
|
+
@property({ type: Boolean, reflect: true }) showCreateAccount: boolean = false;
|
|
73
|
+
@property({ type: Boolean, reflect: true }) showLoginButton: boolean = true;
|
|
74
|
+
@property({ type: String, reflect: true }) username: string = "";
|
|
75
|
+
/** If a theme other than light is provided that will be used ad css properties will be ignored */
|
|
76
|
+
@property({ type: String, reflect: true }) theme?: KnownThemes
|
|
77
|
+
// protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
78
|
+
// return this
|
|
79
|
+
// }
|
|
80
|
+
protected render() {
|
|
81
|
+
if (this.classificationLevel && !ClassificationStyles[this.classificationLevel]) {
|
|
82
|
+
console.warn("Unknown classification", this.classificationLevel)
|
|
83
|
+
this.classificationLevel = ClassificationVariants.None
|
|
84
|
+
}
|
|
85
|
+
const classificationText = this.classificationLevel ? this.classificationText || ClassificationStyles[this.classificationLevel].content : ""
|
|
86
|
+
const header = this.showHeader ? html`<spectric-header ?showCreateAccount=${this.showCreateAccount} .showLoginButton=${this.showLoginButton} username=${ifDefined(this.username)}>
|
|
87
|
+
<slot name="branding" slot="branding"></slot>
|
|
88
|
+
<slot name="name" slot="name"></slot>
|
|
89
|
+
<slot name="center" slot="center"></slot>
|
|
90
|
+
<slot name="end" slot="end"></slot>
|
|
91
|
+
</spectric-header>`: null
|
|
92
|
+
return html`
|
|
93
|
+
${this.classificationLevel && classificationText ? html`
|
|
94
|
+
<!-- Classification Banner -->
|
|
95
|
+
<spectric-banner ${spreadProps({ text: classificationText, headerStyle: ClassificationStyles[this.classificationLevel] })}></spectric-banner>
|
|
96
|
+
`
|
|
97
|
+
: null}
|
|
98
|
+
<spectric-theme theme=${ifDefined(this.theme)}>
|
|
99
|
+
${this.notifications ? this.notifications.map((n) => {
|
|
100
|
+
return html`<spectric-banner ${spreadProps(n)} ></spectric-banner>`
|
|
101
|
+
}) : null}
|
|
102
|
+
${this.headerSticky ? header : null}
|
|
103
|
+
<article>
|
|
104
|
+
${this.headerSticky ? null : header}
|
|
105
|
+
<section class="spectric-page">
|
|
106
|
+
<slot name="content"></slot>
|
|
107
|
+
<slot></slot>
|
|
108
|
+
</section>
|
|
109
|
+
</article>
|
|
110
|
+
</spectric-theme>
|
|
111
|
+
${this.classificationLevel && classificationText ?
|
|
112
|
+
html`<spectric-banner ${spreadProps({ text: classificationText, headerStyle: ClassificationStyles[this.classificationLevel] })}></spectric-banner>` :
|
|
113
|
+
null
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
`
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// let p = document.createElement("spectric-page")
|
|
121
|
+
// p.addEventListener("theme-change",(e)=>{
|
|
122
|
+
|
|
123
|
+
// })
|
|
124
|
+
// let t = document.createElement("spectric-theme")
|
|
125
|
+
// t.addEventListener("theme-change",(e)=>{})
|
|
126
|
+
// interface SpectricEventsMaps extends HeaderEventMap,ThemeEventMap,BannerEventMap {
|
|
127
|
+
|
|
128
|
+
// }
|
|
129
|
+
type SpectricEventsMaps = HeaderEventMap & ThemeEventMap & BannerEventMap
|
|
130
|
+
|
|
131
|
+
declare global {
|
|
132
|
+
interface HTMLElementTagNameMap {
|
|
133
|
+
/**
|
|
134
|
+
* {@link SpectricPage}
|
|
135
|
+
*/
|
|
136
|
+
"spectric-page": HTMLElementTagWithEvents<SpectricPage, SpectricEventsMaps>
|
|
137
|
+
}
|
|
138
|
+
namespace JSX {
|
|
139
|
+
interface IntrinsicElements {
|
|
140
|
+
/**
|
|
141
|
+
* {@link SpectricPage}
|
|
142
|
+
*/
|
|
143
|
+
"spectric-page": ReactElementWithPropsAndEvents<SpectricPage, PageProps, SpectricEventsMaps>;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
namespace React {
|
|
147
|
+
namespace JSX {
|
|
148
|
+
interface IntrinsicElements {
|
|
149
|
+
/**
|
|
150
|
+
* {@link SpectricPage}
|
|
151
|
+
*/
|
|
152
|
+
"spectric-page": ReactElementWithPropsAndEvents<SpectricPage, PageProps, SpectricEventsMaps>;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { CSSResultGroup, html, LitElement } from 'lit';
|
|
2
|
+
import styles from './panel.css.ts';
|
|
3
|
+
import { customElement } from 'lit/decorators/custom-element.js';
|
|
4
|
+
import { property } from 'lit/decorators/property.js';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Spectric Panel visually seperates content areas and automatically adjusts the component colors that are nested inside.
|
|
11
|
+
* */
|
|
12
|
+
@customElement("spectric-panel")
|
|
13
|
+
export class SpectricPanel extends LitElement {
|
|
14
|
+
static styles?: CSSResultGroup | undefined = styles;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Specify the layer level and override any existing levels based on hierarchy
|
|
18
|
+
*/
|
|
19
|
+
@property({ type: Number, reflect: true })
|
|
20
|
+
level = 0;
|
|
21
|
+
|
|
22
|
+
@property({ attribute: false })
|
|
23
|
+
layers?: NodeListOf<SpectricPanel>;
|
|
24
|
+
|
|
25
|
+
updated() {
|
|
26
|
+
if (!this.layers) {
|
|
27
|
+
this.layers = this.querySelectorAll(
|
|
28
|
+
"spectric-panel"
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
this.layers.forEach((item: SpectricPanel) => {
|
|
33
|
+
(item).setAttribute(
|
|
34
|
+
'level',
|
|
35
|
+
((this.level + 1) % 4).toString()
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
this.dispatchEvent(
|
|
40
|
+
new CustomEvent("use-layer", {
|
|
41
|
+
bubbles: true,
|
|
42
|
+
cancelable: true,
|
|
43
|
+
composed: true,
|
|
44
|
+
detail: {
|
|
45
|
+
layer: this,
|
|
46
|
+
level: this.level,
|
|
47
|
+
},
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
render() {
|
|
53
|
+
return html` <slot></slot> `;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { css, CSSResultGroup, html, LitElement, PropertyValues } from 'lit';
|
|
2
|
+
import { customElement } from 'lit/decorators/custom-element.js';
|
|
3
|
+
import { property } from 'lit/decorators/property.js';
|
|
4
|
+
import { HTMLElementTagWithEvents, ReactElementWithPropsAndEvents } from './types';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export interface CSSProps {
|
|
9
|
+
"--primary": string,
|
|
10
|
+
"--secondary": string,
|
|
11
|
+
"--tertiary": string,
|
|
12
|
+
"--disabled": string,
|
|
13
|
+
"--background": string,
|
|
14
|
+
"--background-inverse": string,
|
|
15
|
+
"--text-primary": string
|
|
16
|
+
"--text-secondary": string
|
|
17
|
+
"--text-on-color": string
|
|
18
|
+
"--border-radius": string
|
|
19
|
+
}
|
|
20
|
+
type InputType = {
|
|
21
|
+
control: "color" | "text"
|
|
22
|
+
}
|
|
23
|
+
export const CSSPropsControls: Record<keyof CSSProps, InputType> = {
|
|
24
|
+
"--primary": { control: "color" },
|
|
25
|
+
"--secondary": { control: "color" },
|
|
26
|
+
"--tertiary": { control: "color" },
|
|
27
|
+
"--disabled": { control: "color" },
|
|
28
|
+
"--background": { control: "color" },
|
|
29
|
+
"--background-inverse": { control: "color" },
|
|
30
|
+
"--text-primary": { control: "color" },
|
|
31
|
+
"--text-secondary": { control: "color" },
|
|
32
|
+
"--text-on-color": { control: "color" },
|
|
33
|
+
"--border-radius": { control: "text" },
|
|
34
|
+
}
|
|
35
|
+
const dark = {
|
|
36
|
+
"--secondary": "#77878b",
|
|
37
|
+
"--tertiary": "#c7c7c7",
|
|
38
|
+
"--disabled": "#000000",
|
|
39
|
+
"--text-primary": "#cccccc",
|
|
40
|
+
"--text-secondary": "#cccccc",
|
|
41
|
+
"--text-on-color": "#ededed",
|
|
42
|
+
"--background": "#181818",
|
|
43
|
+
"--background-inverse": "#37373d",
|
|
44
|
+
}
|
|
45
|
+
const spectric = {
|
|
46
|
+
...dark,
|
|
47
|
+
"--primary": "#ffd45a",
|
|
48
|
+
"--text-on-color": "#4f4f4f",
|
|
49
|
+
}
|
|
50
|
+
const Themes = {
|
|
51
|
+
undefined: {},
|
|
52
|
+
light: {},
|
|
53
|
+
dark,
|
|
54
|
+
spectric,
|
|
55
|
+
spectricFlat: {
|
|
56
|
+
...spectric,
|
|
57
|
+
"--border-radius": "1px",
|
|
58
|
+
}
|
|
59
|
+
} as const
|
|
60
|
+
export type KnownThemes = keyof typeof Themes
|
|
61
|
+
|
|
62
|
+
export const ThemeSelections = Object.fromEntries(Object.keys(Themes).map(k => [k, k])) as { [k in keyof typeof Themes]: k }
|
|
63
|
+
|
|
64
|
+
type ThemeProps = {
|
|
65
|
+
theme?: KnownThemes
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
const theme = `
|
|
70
|
+
--spectric-background: var(--background,#ffffff);
|
|
71
|
+
--spectric-background-hover:var(--background-hover,rgba(141, 141, 141, 0.12));
|
|
72
|
+
--spectric-background-inverse: var(--background-inverse,#f4f4f4);
|
|
73
|
+
--spectric-background-inverse-hover: var(--background-inverse-hover,#474747);
|
|
74
|
+
--spectric-border-radius: var(--border-radius,.4em);
|
|
75
|
+
--spectric-primary:var(--primary,#1ea7fd);
|
|
76
|
+
--spectric-secondary: var(--secondary,#77878b);
|
|
77
|
+
--spectric-tertiary: var(--tertiary,#0f62fe);
|
|
78
|
+
--spectric-disabled: var(--disabled,#c6c6c6);
|
|
79
|
+
|
|
80
|
+
/* panel */
|
|
81
|
+
--panel-color:var(--spectric-background-inverse);
|
|
82
|
+
--panel-color-inverse:var(--spectric-background);
|
|
83
|
+
--spectric-border-disabled: var(--disabled);
|
|
84
|
+
|
|
85
|
+
/*inputs*/
|
|
86
|
+
--spectric-input-color: var(--panel-color-inverse);
|
|
87
|
+
--spectric-input-bottom: var(--panel-color);
|
|
88
|
+
|
|
89
|
+
--spectric-text-on-color: var(--text-on-color,#ffffff);
|
|
90
|
+
--spectric-text-on-color-disabled: var(--text-on-color-disabled,#8d8d8d);
|
|
91
|
+
--spectric-text-placeholder: var(--text-placeholder,rgba(22, 22, 22, 0.4));
|
|
92
|
+
--spectric-text-primary: var(--text-primary,#161616);
|
|
93
|
+
--spectric-text-secondary: var(--text-secondary,#525252);
|
|
94
|
+
/* Buttons */
|
|
95
|
+
--spectric-button-separator: #e0e0e0;
|
|
96
|
+
--spectric-button-primary: var(--primary,#1ea7fd);
|
|
97
|
+
--spectric-button-secondary: var(--secondary,#77878b);
|
|
98
|
+
--spectric-button-tertiary: var(--tertiary);
|
|
99
|
+
--spectric-button-danger-primary: #da1e28;
|
|
100
|
+
--spectric-button-danger-secondary: #da1e28;
|
|
101
|
+
--spectric-button-danger-active: #750e13;
|
|
102
|
+
--spectric-button-primary-active: #002d9c;
|
|
103
|
+
--spectric-button-secondary-active: #6f6f6f;
|
|
104
|
+
--spectric-button-tertiary-active: #002d9c;
|
|
105
|
+
--spectric-button-danger-hover: #b81921;
|
|
106
|
+
--spectric-button-primary-hover: #0050e6;
|
|
107
|
+
--spectric-button-secondary-hover: #474747;
|
|
108
|
+
--spectric-button-tertiary-hover: #0050e6;
|
|
109
|
+
--spectric-text-on-color-disabled: var(--disabled,#c6c6c6)
|
|
110
|
+
--spectric-button-disabled: #c6c6c6;
|
|
111
|
+
color: var(--spectric-text-primary);
|
|
112
|
+
`
|
|
113
|
+
|
|
114
|
+
export interface ThemeChangeEvent {
|
|
115
|
+
old?: string,
|
|
116
|
+
new?: string
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface ThemeEventMap {
|
|
120
|
+
"theme-change": (event: CustomEvent<ThemeChangeEvent>) => void;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@customElement("spectric-theme")
|
|
125
|
+
export class SpectricThemeProvider extends LitElement {
|
|
126
|
+
static styles?: CSSResultGroup | undefined = css`:host{
|
|
127
|
+
display:contents;
|
|
128
|
+
}`;
|
|
129
|
+
@property({ reflect: true }) theme: KnownThemes = "undefined";
|
|
130
|
+
protected updated(_changedProperties: PropertyValues): void {
|
|
131
|
+
if (_changedProperties.has("theme") && this.theme != _changedProperties.get("theme")) {
|
|
132
|
+
const eventDetails: ThemeChangeEvent = {
|
|
133
|
+
old: _changedProperties.get("theme"),
|
|
134
|
+
new: this.theme
|
|
135
|
+
};
|
|
136
|
+
this.dispatchEvent(new CustomEvent<ThemeChangeEvent>("theme-change", { detail: eventDetails, bubbles: true, composed: true }))
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
protected render() {
|
|
140
|
+
let currentTheme = Object.keys(Themes).includes(this.theme) ? this.theme : "undefined"
|
|
141
|
+
let style = Object.entries(
|
|
142
|
+
Themes[currentTheme]
|
|
143
|
+
)
|
|
144
|
+
.map(entry => `${entry[0]}:${entry[1]};`)
|
|
145
|
+
.join("\n")
|
|
146
|
+
|
|
147
|
+
return html`
|
|
148
|
+
${this.theme && this.theme !== "light" ? html`
|
|
149
|
+
<style>:host{
|
|
150
|
+
${style};
|
|
151
|
+
${theme}
|
|
152
|
+
}
|
|
153
|
+
/* Webkit psudo elements don't pick up variables defined by the host */
|
|
154
|
+
::-webkit-scrollbar-thumb {
|
|
155
|
+
background: var(--spectric-background-inverse,#393939);
|
|
156
|
+
border-radius: var(--spectric-border-radius,4em);
|
|
157
|
+
-webkit-border-radius: var(--spectric-border-radius,4em);
|
|
158
|
+
padding-top: 1px;
|
|
159
|
+
padding-bottom: 1px;
|
|
160
|
+
}
|
|
161
|
+
::-webkit-scrollbar-thumb:hover {
|
|
162
|
+
background: var(--spectric-background-inverse-hover,#474747);
|
|
163
|
+
|
|
164
|
+
}
|
|
165
|
+
::-webkit-scrollbar-corner {
|
|
166
|
+
background: var(--spectric-background, #ffffff);
|
|
167
|
+
}
|
|
168
|
+
/* Buttons */
|
|
169
|
+
|
|
170
|
+
::-webkit-scrollbar-button:single-button {
|
|
171
|
+
background-color: transparent;
|
|
172
|
+
display: block;
|
|
173
|
+
border-style: solid;
|
|
174
|
+
}
|
|
175
|
+
/* Up */
|
|
176
|
+
::-webkit-scrollbar-button:single-button:vertical:decrement {
|
|
177
|
+
border-width: 0 5px 5px 5px;
|
|
178
|
+
border-color: var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-background-inverse,#393939) var(--spectric-background, #ffffff);
|
|
179
|
+
}
|
|
180
|
+
::-webkit-scrollbar-button:single-button:vertical:decrement:hover {
|
|
181
|
+
border-color: var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-background-inverse-hover,#474747) var(--spectric-background, #ffffff);
|
|
182
|
+
}
|
|
183
|
+
/* Down */
|
|
184
|
+
::-webkit-scrollbar-button:single-button:vertical:increment {
|
|
185
|
+
border-width: 5px 5px 0 5px;
|
|
186
|
+
border-color: var(--spectric-background-inverse,#393939) var(--spectric-background, #ffffff) transparent var(--spectric-background, #ffffff);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
::-webkit-scrollbar-button:vertical:single-button:increment:hover {
|
|
190
|
+
border-color: var(--spectric-background-inverse-hover,#474747) var(--spectric-background, #ffffff) transparent var(--spectric-background, #ffffff);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/* Left */
|
|
194
|
+
::-webkit-scrollbar-button:single-button:horizontal:decrement {
|
|
195
|
+
border-width: 5px 5px 5px 0;
|
|
196
|
+
border-color:var(--spectric-background, #ffffff) var(--spectric-background-inverse,#393939) var(--spectric-background, #ffffff) var(--spectric-background, #ffffff);
|
|
197
|
+
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
::-webkit-scrollbar-button:single-button:horizontal:decrement:hover {
|
|
201
|
+
border-width: 5px 5px 5px 0;
|
|
202
|
+
border-color:var(--spectric-background, #ffffff) var(--spectric-background-inverse-hover,#474747) var(--spectric-background, #ffffff) var(--spectric-background, #ffffff);
|
|
203
|
+
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
/* Right */
|
|
209
|
+
::-webkit-scrollbar-button:single-button:horizontal:increment {
|
|
210
|
+
border-width: 5px 0 5px 5px;
|
|
211
|
+
border-color:var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-background-inverse,#393939);
|
|
212
|
+
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
::-webkit-scrollbar-button:single-button:horizontal:increment:hover {
|
|
216
|
+
border-width: 5px 0 5px 5px;
|
|
217
|
+
border-color:var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-background, #ffffff) var(--spectric-background-inverse-hover,#474747);
|
|
218
|
+
|
|
219
|
+
}
|
|
220
|
+
</style>`: null}
|
|
221
|
+
<slot></slot>
|
|
222
|
+
`
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
declare global {
|
|
227
|
+
//Add events that bubble up to a "global events map"
|
|
228
|
+
interface SpectricGlobalEvents extends ThemeEventMap { }
|
|
229
|
+
interface HTMLElementTagNameMap {
|
|
230
|
+
"spectric-theme": HTMLElementTagWithEvents<SpectricThemeProvider, ThemeEventMap>
|
|
231
|
+
}
|
|
232
|
+
namespace JSX {
|
|
233
|
+
interface IntrinsicElements {
|
|
234
|
+
/**
|
|
235
|
+
* {@link SpectricThemeProvider}
|
|
236
|
+
*/
|
|
237
|
+
"spectric-theme": ReactElementWithPropsAndEvents<SpectricThemeProvider, ThemeProps, ThemeEventMap>;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
namespace React {
|
|
241
|
+
namespace JSX {
|
|
242
|
+
interface IntrinsicElements {
|
|
243
|
+
/**
|
|
244
|
+
* {@link SpectricThemeProvider}
|
|
245
|
+
*/
|
|
246
|
+
"spectric-theme": ReactElementWithPropsAndEvents<SpectricThemeProvider, ThemeProps, ThemeEventMap>;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export default css`
|
|
3
|
+
:host{
|
|
4
|
+
display: inline-block;
|
|
5
|
+
--text-on-color: var(--spectric-text-on-color, #ffffff);
|
|
6
|
+
--text-on-color-disabled: var(--spectric-text-on-color-disabled, #8d8d8d);
|
|
7
|
+
--text-placeholder: var(--spectric-text-placeholder, rgba(22, 22, 22, 0.4));
|
|
8
|
+
--text-primary: var(--spectric-text-primary, #161616);
|
|
9
|
+
--text-secondary: var(--spectric-text-secondary, #525252);
|
|
10
|
+
--button-border-radius: var(--spectric-border-radius,.4em);
|
|
11
|
+
--button-separator: var(--spectric-button-separator, #e0e0e0);
|
|
12
|
+
--button-primary: var(--spectric-button-primary,#1ea7fd);
|
|
13
|
+
--button-secondary: var(--spectric-button-secondary, #77878b);
|
|
14
|
+
--button-tertiary: var(--spectric-button-tertiary, #0f62fe);
|
|
15
|
+
--button-danger-primary: var(--spectric-button-danger-primary, #da1e28);
|
|
16
|
+
--button-danger-secondary: var(--spectric-button-danger-secondary, #da1e28);
|
|
17
|
+
--button-danger-active: var(--spectric-button-danger-active, #750e13);
|
|
18
|
+
--button-primary-active: var(--spectric-button-primary-active, #002d9c);
|
|
19
|
+
--button-secondary-active: var(--spectric-button-secondary-active, #6f6f6f);
|
|
20
|
+
--button-tertiary-active: var(--spectric-button-tertiary-active, #002d9c);
|
|
21
|
+
--button-danger-hover: var(--spectric-button-danger-hover, #b81921);
|
|
22
|
+
--button-primary-hover: var(--spectric-button-primary-hover, #0050e6);
|
|
23
|
+
--button-secondary-hover: var(--spectric-button-secondary-hover, #474747);
|
|
24
|
+
--button-tertiary-hover: var(--spectric-button-tertiary-hover, #0050e6);
|
|
25
|
+
--button-disabled: var(--spectric-button-disabled, #c6c6c6);
|
|
26
|
+
}
|
|
27
|
+
:host([disabled]) { pointer-events: none }
|
|
28
|
+
|
|
29
|
+
.spectric-button {
|
|
30
|
+
pointer-events:none;
|
|
31
|
+
position: relative;
|
|
32
|
+
display: inline-block;
|
|
33
|
+
cursor: pointer;
|
|
34
|
+
border: 0;
|
|
35
|
+
border-radius: var(--button-border-radius);
|
|
36
|
+
font-weight: 700;
|
|
37
|
+
line-height: 2em;
|
|
38
|
+
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
|
39
|
+
overflow:hidden;
|
|
40
|
+
}
|
|
41
|
+
.animation{
|
|
42
|
+
pointer-events: none;
|
|
43
|
+
transition: background-color 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), opacity 0.4s cubic-bezier(0.25, 0.8, 0.5, 1);
|
|
44
|
+
width: 100%;
|
|
45
|
+
height: 100%;
|
|
46
|
+
position: absolute;
|
|
47
|
+
left: 0;
|
|
48
|
+
top: 0;
|
|
49
|
+
}
|
|
50
|
+
.animation::before {
|
|
51
|
+
content: "";
|
|
52
|
+
position: absolute;
|
|
53
|
+
top: 0;
|
|
54
|
+
left: 0 /* rtl:ignore */;
|
|
55
|
+
width: 100%;
|
|
56
|
+
height: 100%;
|
|
57
|
+
}
|
|
58
|
+
:host(:active) .animation::after {
|
|
59
|
+
box-shadow: 0 0 0 0 black;
|
|
60
|
+
position: absolute;
|
|
61
|
+
opacity: 1;
|
|
62
|
+
transition: 0s;
|
|
63
|
+
}
|
|
64
|
+
.animation::after{
|
|
65
|
+
content: "";
|
|
66
|
+
display: block;
|
|
67
|
+
position: absolute;
|
|
68
|
+
border-radius: var(--border-radius);
|
|
69
|
+
left: 0;
|
|
70
|
+
top: 0;
|
|
71
|
+
width: 100%;
|
|
72
|
+
height: 100%;
|
|
73
|
+
opacity: 0;
|
|
74
|
+
transition: all .5s;
|
|
75
|
+
box-shadow: 0 0 30px black inset;
|
|
76
|
+
}
|
|
77
|
+
.spectric-button.spectric-button--secondary .animation::after , .spectric-button.spectric-button--text .animation::after {
|
|
78
|
+
box-shadow: 0 0 30px white inset;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.spectric-button:disabled{
|
|
82
|
+
cursor: not-allowed;
|
|
83
|
+
pointer-events: none;
|
|
84
|
+
filter: contrast(0.5);
|
|
85
|
+
/* background-color:var(--button-disabled); */
|
|
86
|
+
color:var(--text-on-color-disabled);
|
|
87
|
+
}
|
|
88
|
+
.spectric-button:disabled .animation , :host(:disabled:hover) .animation{
|
|
89
|
+
background-color: rgba(0, 0, 0, 0);
|
|
90
|
+
opacity:1
|
|
91
|
+
}
|
|
92
|
+
.spectric-button-danger--true:hover{
|
|
93
|
+
background-color:var(--button-danger-hover);
|
|
94
|
+
}
|
|
95
|
+
.spectric-button--primary.spectric-button-danger--true {
|
|
96
|
+
background-color:var(--button-danger-primary);
|
|
97
|
+
box-shadow:none;
|
|
98
|
+
}
|
|
99
|
+
.spectric-button--secondary.spectric-button-danger--true {
|
|
100
|
+
color: var(--text-on-color);
|
|
101
|
+
background-color:color-mix(in srgb, var(--button-danger-primary) 70%, transparent);
|
|
102
|
+
box-shadow:none;
|
|
103
|
+
}
|
|
104
|
+
.spectric-button--text.spectric-button-danger--true {
|
|
105
|
+
color:var(--button-danger-primary);
|
|
106
|
+
|
|
107
|
+
}
|
|
108
|
+
:host(:hover) .spectric-button--text.spectric-button-danger--true {
|
|
109
|
+
background-color:var(--button-danger-primary);
|
|
110
|
+
color:var(--text-on-color)
|
|
111
|
+
}
|
|
112
|
+
:host(:hover) .animation{
|
|
113
|
+
background: currentColor;
|
|
114
|
+
opacity: 0.15;
|
|
115
|
+
}
|
|
116
|
+
.spectric-button--primary {
|
|
117
|
+
box-shadow: color-mix(in srgb, var(--button-primary) 50%, transparent) 0px 0px 0px 1px inset;
|
|
118
|
+
background-color: var(--button-primary);
|
|
119
|
+
color: var(--text-on-color);
|
|
120
|
+
}
|
|
121
|
+
:host > .spectric-button--primary:focus {
|
|
122
|
+
outline-color: var(--button-secondary);
|
|
123
|
+
outline-width: thin;
|
|
124
|
+
outline-style: solid;
|
|
125
|
+
}
|
|
126
|
+
:host > .spectric-button--secondary:focus {
|
|
127
|
+
outline-color: var(--button-primary);
|
|
128
|
+
outline-width: thin;
|
|
129
|
+
outline-style: solid;
|
|
130
|
+
}
|
|
131
|
+
:host > .spectric-button--text:focus {
|
|
132
|
+
outline-color: var(--button-primary);
|
|
133
|
+
outline-width: thin;
|
|
134
|
+
outline-style: solid;
|
|
135
|
+
}
|
|
136
|
+
/* :host([variant="text"]):focus-within:focus,button:focus, button:focus-within, button:focus-visible{
|
|
137
|
+
outline-color: red;
|
|
138
|
+
} */
|
|
139
|
+
.spectric-button--secondary {
|
|
140
|
+
background-color:transparent;
|
|
141
|
+
box-shadow: var(--button-secondary) 0px 0px 0px 1px inset;
|
|
142
|
+
color: var(--button-secondary);
|
|
143
|
+
}
|
|
144
|
+
.spectric-button--text {
|
|
145
|
+
background-color: transparent;
|
|
146
|
+
color: var(--text-secondary);
|
|
147
|
+
}
|
|
148
|
+
.spectric-button--small {
|
|
149
|
+
padding: 5px 10px;
|
|
150
|
+
font-size: 12px;
|
|
151
|
+
}
|
|
152
|
+
.spectric-button--medium {
|
|
153
|
+
padding: 6px 17px;
|
|
154
|
+
font-size: 14px;
|
|
155
|
+
}
|
|
156
|
+
.spectric-button--large {
|
|
157
|
+
padding: 7px 24px;
|
|
158
|
+
font-size: 16px;
|
|
159
|
+
}
|
|
160
|
+
`
|