@hotosm/ui 0.2.0-b3 → 0.2.0-b4
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 +32 -24
- package/components/header/header.d.ts +30 -0
- package/components/header/header.js +237 -0
- package/components/header/header.ts +237 -0
- package/components/icons.js +6 -0
- package/components/icons.ts +84 -0
- package/components/index.d.ts +127 -4
- package/components/index.js +125 -4
- package/components/index.ts +259 -0
- package/components/{Toolbar.d.ts → toolbar/toolbar.d.ts} +1 -3
- package/components/{Toolbar.js → toolbar/toolbar.js} +10 -12
- package/components/toolbar/toolbar.ts +128 -0
- package/components/{Tracking.d.ts → tracking/tracking.d.ts} +1 -3
- package/components/{Tracking.js → tracking/tracking.js} +2 -5
- package/components/tracking/tracking.ts +173 -0
- package/dist/components.js +18122 -51
- package/dist/style.css +1 -0
- package/package.json +6 -13
- package/react/Header.js +4 -1
- package/react/Toolbar.js +9 -9
- package/react/Tracking.js +1 -1
- package/react/index.d.ts +0 -1
- package/react/index.js +0 -1
- package/theme/sl-custom.css +74 -0
- package/components/Button.d.ts +0 -16
- package/components/Button.js +0 -75
- package/components/Header.d.ts +0 -16
- package/components/Header.js +0 -152
- package/dist/assets/logo-CqlPtOQW.png +0 -0
- package/dist/styles.css +0 -1092
- package/react/Button.d.ts +0 -2
- package/react/Button.js +0 -14
|
@@ -4,16 +4,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import "
|
|
8
|
-
import '@shoelace-style/shoelace/dist/themes/light.css';
|
|
9
|
-
import '@shoelace-style/shoelace/dist/themes/dark.css';
|
|
7
|
+
import "../../theme/sl-custom.css";
|
|
10
8
|
import '@shoelace-style/shoelace/dist/components/button/button.js';
|
|
11
9
|
import '@shoelace-style/shoelace/dist/components/button-group/button-group.js';
|
|
12
10
|
import '@shoelace-style/shoelace/dist/components/icon/icon.js';
|
|
13
11
|
import '@shoelace-style/shoelace/dist/components/tooltip/tooltip.js';
|
|
14
12
|
import { LitElement, css, html } from "lit";
|
|
15
13
|
import { property } from "lit/decorators.js";
|
|
16
|
-
import registerBundledIcons from '
|
|
14
|
+
import registerBundledIcons from '../../components/icons';
|
|
17
15
|
registerBundledIcons();
|
|
18
16
|
// import { cva } from "class-variance-authority";
|
|
19
17
|
// const toolbarStyle = cva(
|
|
@@ -37,35 +35,35 @@ export class Toolbar extends LitElement {
|
|
|
37
35
|
// As the original event is also named 'click'
|
|
38
36
|
// stop propagation of the original event
|
|
39
37
|
e.stopPropagation();
|
|
40
|
-
this.dispatchEvent(new Event("
|
|
38
|
+
this.dispatchEvent(new Event("undo"));
|
|
41
39
|
};
|
|
42
40
|
this.redo = (e) => {
|
|
43
41
|
e.stopPropagation();
|
|
44
|
-
this.dispatchEvent(new Event("
|
|
42
|
+
this.dispatchEvent(new Event("redo"));
|
|
45
43
|
};
|
|
46
44
|
this.bold = (e) => {
|
|
47
45
|
e.stopPropagation();
|
|
48
|
-
this.dispatchEvent(new Event("
|
|
46
|
+
this.dispatchEvent(new Event("bold"));
|
|
49
47
|
};
|
|
50
48
|
this.italic = (e) => {
|
|
51
49
|
e.stopPropagation();
|
|
52
|
-
this.dispatchEvent(new Event("
|
|
50
|
+
this.dispatchEvent(new Event("italic"));
|
|
53
51
|
};
|
|
54
52
|
this.underline = (e) => {
|
|
55
53
|
e.stopPropagation();
|
|
56
|
-
this.dispatchEvent(new Event("
|
|
54
|
+
this.dispatchEvent(new Event("underline"));
|
|
57
55
|
};
|
|
58
56
|
this.alignLeft = (e) => {
|
|
59
57
|
e.stopPropagation();
|
|
60
|
-
this.dispatchEvent(new Event("
|
|
58
|
+
this.dispatchEvent(new Event("leftalign"));
|
|
61
59
|
};
|
|
62
60
|
this.alignCenter = (e) => {
|
|
63
61
|
e.stopPropagation();
|
|
64
|
-
this.dispatchEvent(new Event("
|
|
62
|
+
this.dispatchEvent(new Event("centeralign"));
|
|
65
63
|
};
|
|
66
64
|
this.alignRight = (e) => {
|
|
67
65
|
e.stopPropagation();
|
|
68
|
-
this.dispatchEvent(new Event("
|
|
66
|
+
this.dispatchEvent(new Event("rightalign"));
|
|
69
67
|
};
|
|
70
68
|
}
|
|
71
69
|
// class=${toolbarStyle({
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import "../../theme/sl-custom.css";
|
|
2
|
+
|
|
3
|
+
import '@shoelace-style/shoelace/dist/components/button/button.js';
|
|
4
|
+
import '@shoelace-style/shoelace/dist/components/button-group/button-group.js';
|
|
5
|
+
import '@shoelace-style/shoelace/dist/components/icon/icon.js';
|
|
6
|
+
import '@shoelace-style/shoelace/dist/components/tooltip/tooltip.js';
|
|
7
|
+
|
|
8
|
+
import { LitElement, css, html, unsafeCSS } from "lit";
|
|
9
|
+
import { property } from "lit/decorators.js";
|
|
10
|
+
|
|
11
|
+
import registerBundledIcons from '../../components/icons';
|
|
12
|
+
|
|
13
|
+
registerBundledIcons();
|
|
14
|
+
|
|
15
|
+
// import { cva } from "class-variance-authority";
|
|
16
|
+
|
|
17
|
+
// const toolbarStyle = cva(
|
|
18
|
+
// "some-css-var",
|
|
19
|
+
// {
|
|
20
|
+
// variants: {
|
|
21
|
+
// someProperty: {
|
|
22
|
+
// true: "some-css-var",
|
|
23
|
+
// false: "some-css-var",
|
|
24
|
+
// },
|
|
25
|
+
// },
|
|
26
|
+
// },
|
|
27
|
+
// );
|
|
28
|
+
|
|
29
|
+
export class Toolbar extends LitElement {
|
|
30
|
+
@property() name = "hot-toolbar";
|
|
31
|
+
|
|
32
|
+
/** Change the position of the tooltips relative to buttons. */
|
|
33
|
+
@property({ type: String, attribute: "tooltip-position" }) tooltipPosition = "top";
|
|
34
|
+
|
|
35
|
+
static styles = [
|
|
36
|
+
css`
|
|
37
|
+
@unocss-placeholder;
|
|
38
|
+
`,
|
|
39
|
+
// unsafeCSS(reset),
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
// class=${toolbarStyle({
|
|
43
|
+
// someProperty: this.someProperty,
|
|
44
|
+
// })}
|
|
45
|
+
protected render() {
|
|
46
|
+
return html`
|
|
47
|
+
<div class="button-group-toolbar">
|
|
48
|
+
${this.renderButtonGroup('History', [
|
|
49
|
+
{ content: 'Undo', icon: 'arrow-counterclockwise', label: 'Undo', action: this.undo },
|
|
50
|
+
{ content: 'Redo', icon: 'arrow-clockwise', label: 'Redo', action: this.redo }
|
|
51
|
+
])}
|
|
52
|
+
${this.renderButtonGroup('Formatting', [
|
|
53
|
+
{ content: 'Bold', icon: 'type-bold', label: 'Bold', action: this.bold },
|
|
54
|
+
{ content: 'Italic', icon: 'type-italic', label: 'Italic', action: this.italic },
|
|
55
|
+
{ content: 'Underline', icon: 'type-underline', label: 'Underline', action: this.underline }
|
|
56
|
+
])}
|
|
57
|
+
${this.renderButtonGroup('Alignment', [
|
|
58
|
+
{ content: 'Align Left', icon: 'justify-left', label: 'Align Left', action: this.alignLeft },
|
|
59
|
+
{ content: 'Align Center', icon: 'justify', label: 'Align Center', action: this.alignCenter },
|
|
60
|
+
{ content: 'Align Right', icon: 'justify-right', label: 'Align Right', action: this.alignRight }
|
|
61
|
+
])}
|
|
62
|
+
</div>
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private renderButtonGroup(label: string, buttons: Array<{ content: string, icon: string, label: string, action?: (e: MouseEvent) => void }>) {
|
|
67
|
+
return html`
|
|
68
|
+
<sl-button-group label=${label}>
|
|
69
|
+
${buttons.map(button => this.renderButton(button))}
|
|
70
|
+
</sl-button-group>
|
|
71
|
+
`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private renderButton({ content, icon, label, action }: { content: string, icon: string, label: string, action?: (e: MouseEvent) => void }) {
|
|
75
|
+
return html`
|
|
76
|
+
<sl-tooltip content=${content} placement="${this.tooltipPosition}">
|
|
77
|
+
<sl-button @click=${action ?? (() => {})}><sl-icon library="bundled" name=${icon} label=${label}></sl-icon></sl-button>
|
|
78
|
+
</sl-tooltip>
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private readonly undo = (e: MouseEvent) => {
|
|
83
|
+
// As the original event is also named 'click'
|
|
84
|
+
// stop propagation of the original event
|
|
85
|
+
e.stopPropagation();
|
|
86
|
+
this.dispatchEvent(new Event("undo"));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private readonly redo = (e: MouseEvent) => {
|
|
90
|
+
e.stopPropagation();
|
|
91
|
+
this.dispatchEvent(new Event("redo"));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private readonly bold = (e: MouseEvent) => {
|
|
95
|
+
e.stopPropagation();
|
|
96
|
+
this.dispatchEvent(new Event("bold"));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private readonly italic = (e: MouseEvent) => {
|
|
100
|
+
e.stopPropagation();
|
|
101
|
+
this.dispatchEvent(new Event("italic"));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private readonly underline = (e: MouseEvent) => {
|
|
105
|
+
e.stopPropagation();
|
|
106
|
+
this.dispatchEvent(new Event("underline"));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private readonly alignLeft = (e: MouseEvent) => {
|
|
110
|
+
e.stopPropagation();
|
|
111
|
+
this.dispatchEvent(new Event("leftalign"));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private readonly alignCenter = (e: MouseEvent) => {
|
|
115
|
+
e.stopPropagation();
|
|
116
|
+
this.dispatchEvent(new Event("centeralign"));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private readonly alignRight = (e: MouseEvent) => {
|
|
120
|
+
e.stopPropagation();
|
|
121
|
+
this.dispatchEvent(new Event("rightalign"));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export default Toolbar;
|
|
126
|
+
|
|
127
|
+
// Define web component
|
|
128
|
+
customElements.define("hot-toolbar", Toolbar);
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import "
|
|
2
|
-
import '@shoelace-style/shoelace/dist/themes/light.css';
|
|
3
|
-
import '@shoelace-style/shoelace/dist/themes/dark.css';
|
|
1
|
+
import "../../theme/sl-custom.css";
|
|
4
2
|
import '@shoelace-style/shoelace/dist/components/alert/alert.js';
|
|
5
3
|
import { LitElement } from "lit";
|
|
6
4
|
declare global {
|
|
@@ -4,13 +4,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import "
|
|
8
|
-
import '@shoelace-style/shoelace/dist/themes/light.css';
|
|
9
|
-
import '@shoelace-style/shoelace/dist/themes/dark.css';
|
|
7
|
+
import "../../theme/sl-custom.css";
|
|
10
8
|
import '@shoelace-style/shoelace/dist/components/alert/alert.js';
|
|
11
9
|
import { LitElement, css, html } from "lit";
|
|
12
10
|
import { property, state } from "lit/decorators.js";
|
|
13
|
-
import registerBundledIcons from '
|
|
11
|
+
import registerBundledIcons from '../../components/icons';
|
|
14
12
|
registerBundledIcons();
|
|
15
13
|
export class Tracking extends LitElement {
|
|
16
14
|
constructor() {
|
|
@@ -133,7 +131,6 @@ Tracking.styles = [
|
|
|
133
131
|
#tracking-header {
|
|
134
132
|
font-weight: var(--sl-font-weight-bold);
|
|
135
133
|
font-size: var(--sl-font-size-large);
|
|
136
|
-
color: #d63f3f;
|
|
137
134
|
text-align: center;
|
|
138
135
|
}
|
|
139
136
|
sl-alert::part(base) {
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import "../../theme/sl-custom.css";
|
|
2
|
+
|
|
3
|
+
import '@shoelace-style/shoelace/dist/components/alert/alert.js';
|
|
4
|
+
|
|
5
|
+
import { LitElement, css, html, unsafeCSS } from "lit";
|
|
6
|
+
import { property, state } from "lit/decorators.js";
|
|
7
|
+
|
|
8
|
+
import registerBundledIcons from '../../components/icons';
|
|
9
|
+
|
|
10
|
+
registerBundledIcons();
|
|
11
|
+
|
|
12
|
+
declare global {
|
|
13
|
+
interface Window {
|
|
14
|
+
_paq: any[];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class Tracking extends LitElement {
|
|
19
|
+
@property() name = "hot-tracking";
|
|
20
|
+
|
|
21
|
+
/** The Matomo site id for tracking. */
|
|
22
|
+
@property({ type: String, attribute: "site-id" }) siteId: string = "";
|
|
23
|
+
|
|
24
|
+
/** The domains to apply tracking. */
|
|
25
|
+
@property({ type: String }) domain: string = "";
|
|
26
|
+
|
|
27
|
+
/** Force display the banner. */
|
|
28
|
+
@property({ type: Boolean }) force: boolean = false;
|
|
29
|
+
|
|
30
|
+
@state() isOpen: boolean = true;
|
|
31
|
+
|
|
32
|
+
static styles = [
|
|
33
|
+
css`
|
|
34
|
+
@unocss-placeholder;
|
|
35
|
+
`,
|
|
36
|
+
|
|
37
|
+
// Temp styles until UnoCSS setup
|
|
38
|
+
css`
|
|
39
|
+
#tracking-header {
|
|
40
|
+
font-weight: var(--sl-font-weight-bold);
|
|
41
|
+
font-size: var(--sl-font-size-large);
|
|
42
|
+
text-align: center;
|
|
43
|
+
}
|
|
44
|
+
sl-alert::part(base) {
|
|
45
|
+
position: absolute;
|
|
46
|
+
bottom: 20px;
|
|
47
|
+
left: 50%;
|
|
48
|
+
transform: translateX(-50%);
|
|
49
|
+
z-index: 1000;
|
|
50
|
+
width: 80vw;
|
|
51
|
+
text-align: center;
|
|
52
|
+
}
|
|
53
|
+
`
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
protected render() {
|
|
57
|
+
return html`<sl-alert
|
|
58
|
+
variant="danger"
|
|
59
|
+
?open=${this.isOpen}
|
|
60
|
+
>
|
|
61
|
+
<sl-icon id="hot-red-text" library="bundled" slot="icon" name="info-circle"></sl-icon>
|
|
62
|
+
|
|
63
|
+
<p id="tracking-header">
|
|
64
|
+
About the information we collect
|
|
65
|
+
</p>
|
|
66
|
+
|
|
67
|
+
<p>
|
|
68
|
+
We use cookies and similar technologies to recognize and analyze your visits,
|
|
69
|
+
and measure traffic usage and activity. You can learn about how we use the data
|
|
70
|
+
about your visit or information you provide reading our
|
|
71
|
+
<a
|
|
72
|
+
style="color: #d63f3f;"
|
|
73
|
+
href="https://www.hotosm.org/privacy"
|
|
74
|
+
target="_blank"
|
|
75
|
+
rel="noopener noreferrer"
|
|
76
|
+
>privacy policy</a>.
|
|
77
|
+
By clicking "I Agree", you consent to the use of cookies.
|
|
78
|
+
</p>
|
|
79
|
+
|
|
80
|
+
<sl-button @click=${(e: MouseEvent) => {this._setAgree(e)}}>I Agree</sl-button>
|
|
81
|
+
<sl-button @click=${(e: MouseEvent) => {this._setDisagree(e)}}>I Do Not Agree</sl-button>
|
|
82
|
+
</sl-alert>`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private _setAgree(_e: MouseEvent) {
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
87
|
+
const _paq = (window._paq = window._paq || []);
|
|
88
|
+
if (_paq.length === 0) return;
|
|
89
|
+
|
|
90
|
+
_paq.push(['rememberConsentGiven']);
|
|
91
|
+
this.isOpen = false;
|
|
92
|
+
localStorage.setItem(`${this.siteId}-matomo-agree`, 'true');
|
|
93
|
+
this.dispatchEvent(new Event('agree', {bubbles: true, composed: true}));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private _setDisagree(_e: MouseEvent) {
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
98
|
+
const _paq = (window._paq = window._paq || []);
|
|
99
|
+
if (_paq.length === 0) return;
|
|
100
|
+
|
|
101
|
+
_paq.push(['forgetConsentGiven']);
|
|
102
|
+
this.isOpen = false;
|
|
103
|
+
localStorage.setItem(`${this.siteId}-matomo-agree`, 'false');
|
|
104
|
+
this.dispatchEvent(new Event('disagree', {bubbles: true, composed: true}));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
connectedCallback() {
|
|
108
|
+
super.connectedCallback();
|
|
109
|
+
|
|
110
|
+
// Close and halt execution if wrong domain
|
|
111
|
+
if (!this.force && window.location.hostname !== this.domain) {
|
|
112
|
+
console.warn(`Matomo init failed. ${window.location.hostname} does not match ${this.domain}.`);
|
|
113
|
+
this.isOpen = false;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const matomoTrackingId = this.siteId;
|
|
118
|
+
|
|
119
|
+
// Close and halt execution if siteId or domain not set
|
|
120
|
+
if (!this.force && (matomoTrackingId.length === 0 || this.domain.length === 0)) {
|
|
121
|
+
console.warn('Matomo init failed. No site id or domains provided.');
|
|
122
|
+
this.isOpen = false;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Close and halt execution if already disagreed
|
|
127
|
+
const consent = localStorage.getItem(`${this.siteId}-matomo-agree`);
|
|
128
|
+
if (consent === 'false') {
|
|
129
|
+
this.isOpen = false;
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Close prompt only if already agreed, continue
|
|
134
|
+
if (consent === 'true') {
|
|
135
|
+
this.isOpen = false;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
console.log(`Setting Matomo tracking for site=${matomoTrackingId} domain=${this.domain}`);
|
|
139
|
+
|
|
140
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
141
|
+
const _paq = (window._paq = window._paq || []);
|
|
142
|
+
|
|
143
|
+
// tracker methods like "setCustomDimension" should be called before "trackPageView"
|
|
144
|
+
_paq.push(['requireConsent']);
|
|
145
|
+
_paq.push(['setDomains', [this.domain]]);
|
|
146
|
+
_paq.push(['trackPageView']);
|
|
147
|
+
_paq.push(['enableLinkTracking']); // Tracks downloads
|
|
148
|
+
_paq.push(['trackVisibleContentImpressions']); // Tracks content
|
|
149
|
+
|
|
150
|
+
(function () {
|
|
151
|
+
const u = '//matomo.hotosm.org/';
|
|
152
|
+
_paq.push(['setTrackerUrl', u + 'matomo.php']);
|
|
153
|
+
_paq.push(['setSiteId', matomoTrackingId]);
|
|
154
|
+
|
|
155
|
+
const d = document;
|
|
156
|
+
const g = d.createElement('script');
|
|
157
|
+
const s = d.getElementsByTagName('script')[0];
|
|
158
|
+
|
|
159
|
+
if (s?.parentNode != null) {
|
|
160
|
+
g.async = true;
|
|
161
|
+
g.src = u + 'matomo.js';
|
|
162
|
+
s.parentNode.insertBefore(g, s);
|
|
163
|
+
} else {
|
|
164
|
+
console.warn('Script insertion failed. Parent node is null.');
|
|
165
|
+
}
|
|
166
|
+
})();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export default Tracking;
|
|
171
|
+
|
|
172
|
+
// Define web component
|
|
173
|
+
customElements.define("hot-tracking", Tracking);
|