@hotosm/ui 0.6.0 → 0.7.0

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 (55) hide show
  1. package/README.md +231 -139
  2. package/dist/chunks/{chunk.GEAU3JJH.js → chunk.252GL6HT.js} +11 -11
  3. package/dist/chunks/{chunk.BORCUX2M.js → chunk.2Y7OBKRQ.js} +1 -1
  4. package/dist/chunks/{chunk.AL4CJN73.js → chunk.5QY2VLMG.js} +1 -1
  5. package/dist/chunks/{chunk.ORZ5STBX.js → chunk.6BGQ256H.js} +2 -2
  6. package/dist/chunks/{chunk.SBUFNOMY.js → chunk.7JIKOYG6.js} +1 -1
  7. package/dist/chunks/{chunk.3LBUXCAP.js → chunk.APYFF2XE.js} +1 -1
  8. package/dist/chunks/{chunk.XEZQ5ZRE.js → chunk.BVHLTKMC.js} +1 -1
  9. package/dist/chunks/chunk.CNUZFRRF.js +105 -0
  10. package/dist/chunks/{chunk.LHZ7Q2M3.js → chunk.FDQFFQX3.js} +5 -5
  11. package/dist/chunks/chunk.FN6G7X23.js +251 -0
  12. package/dist/chunks/{chunk.OICCPCO3.js → chunk.IILWGAOM.js} +1 -1
  13. package/dist/chunks/{chunk.G6ZZSFVM.js → chunk.JYPMFVPO.js} +1 -1
  14. package/dist/chunks/chunk.LKMWWUYT.js +20 -0
  15. package/dist/chunks/{chunk.BD4Q32VT.js → chunk.LVCDAVRU.js} +4 -4
  16. package/dist/chunks/{chunk.ARF626EG.js → chunk.LXN3PNAP.js} +1 -1
  17. package/dist/chunks/chunk.P6GWPFCT.js +32 -0
  18. package/dist/chunks/{chunk.7BVHA4G6.js → chunk.X354U5TL.js} +3 -3
  19. package/dist/chunks/{chunk.7PROWJNJ.js → chunk.XU6UFL27.js} +4 -4
  20. package/dist/chunks/{chunk.MZOQNTPX.js → chunk.ZGC6XD6L.js} +37 -56
  21. package/dist/components/consent/consent.component.d.ts +0 -3
  22. package/dist/components/consent/consent.component.js +1 -1
  23. package/dist/components/consent/consent.js +1 -1
  24. package/dist/components/consent/consent.styles.js +1 -1
  25. package/dist/components/file-input-dropzone/file-input-dropzone.component.d.ts +0 -2
  26. package/dist/components/file-input-dropzone/file-input-dropzone.component.js +1 -1
  27. package/dist/components/file-input-dropzone/file-input-dropzone.js +1 -1
  28. package/dist/components/file-input-dropzone/file-input-dropzone.styles.js +1 -1
  29. package/dist/components/header/header.component.d.ts +0 -4
  30. package/dist/components/header/header.component.js +1 -1
  31. package/dist/components/header/header.js +1 -1
  32. package/dist/components/header/header.styles.js +1 -1
  33. package/dist/components/list-card/list-card.component.d.ts +0 -1
  34. package/dist/components/list-card/list-card.component.js +1 -1
  35. package/dist/components/list-card/list-card.js +1 -1
  36. package/dist/components/list-card/list-card.styles.js +1 -1
  37. package/dist/components/logo/logo.component.js +1 -1
  38. package/dist/components/logo/logo.js +1 -1
  39. package/dist/components/tool-menu/tool-menu.component.d.ts +0 -3
  40. package/dist/components/tool-menu/tool-menu.component.js +1 -1
  41. package/dist/components/tool-menu/tool-menu.js +1 -1
  42. package/dist/components/tool-menu/tool-menu.styles.js +1 -1
  43. package/dist/components/tracking/tracking.component.d.ts +0 -3
  44. package/dist/components/tracking/tracking.component.js +1 -1
  45. package/dist/components/tracking/tracking.js +1 -1
  46. package/dist/hotosm-ui.js +1 -1
  47. package/dist/style-core.css +1 -0
  48. package/dist/style.css +1 -14
  49. package/dist/themes/hot-wa.css +152 -115
  50. package/dist/themes/hot.css +1 -1
  51. package/package.json +5 -3
  52. package/dist/chunks/chunk.CQO3GWTI.js +0 -32
  53. package/dist/chunks/chunk.PLECT4NZ.js +0 -20
  54. package/dist/chunks/chunk.U4AAC5ID.js +0 -239
  55. package/dist/chunks/chunk.WTTPHBL3.js +0 -105
package/README.md CHANGED
@@ -44,176 +44,268 @@
44
44
  🎯 <strong>Roadmap / Tasks</strong>:
45
45
  <a href="https://github.com/orgs/hotosm/projects/37/views/3" target="_blank">https://github.com/orgs/hotosm/projects/37/views/3</a>
46
46
  </p>
47
-
48
-
49
47
  <!-- markdownlint-enable -->
50
48
 
51
49
  ---
52
50
 
53
- ## Shared UI Components with HOT Theming
51
+ ## Overview
54
52
 
55
- This repository contains advice on how to use the WebAwesome
56
- [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
57
- library, references to the HOTOSM style guide, and a few 'wrapper'
58
- components to assist development:
53
+ Shared [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components)
54
+ built with [Lit](https://lit.dev) and themed for HOTOSM tools using
55
+ [WebAwesome](https://webawesome.com) primitives.
59
56
 
60
- 1. Reduced code duplication across HOT tools (we repeat a lot!)
61
- 2. Simplified developer experience to create a HOT app.
62
- 3. Reasonably consistent theming and style across tools.
57
+ **Goals:**
63
58
 
64
- The main goal of this project is not to re-invent the wheel, or add an extra burden
65
- of development and maintenance. It should include a minimal number of
66
- components, such as:
59
+ - Reduce code duplication across HOT tools.
60
+ - Provide a consistent HOT look-and-feel out of the box.
61
+ - Keep the component set small and focused (header, sidebar, footer, etc.).
67
62
 
68
- - Header, including auth flows (OSM, Google) and login info.
69
- - Sidebar with links to extra resources.
70
- - Footer with links.
63
+ **WebAwesome version:** `3.2.1`
71
64
 
72
- ## Quick start
73
-
74
- Current HOTOSM UI version used: `0.3.1-b5`
75
- Current WebAwesome version used: `3.2.1`
65
+ ---
76
66
 
77
- ### Install WebAwesome
67
+ ## Installation
78
68
 
79
69
  ```bash
80
- pnpm install "@awesome.me/webawesome@3.2.1"
70
+ pnpm install @hotosm/ui @awesome.me/webawesome@3.2.1
81
71
  ```
82
72
 
83
73
  > [!NOTE]
84
- > It's important to pin the version of web awesome used to the version in this
85
- > library, to avoid any conflicts and incompatibilities between components.
74
+ > `@awesome.me/webawesome` is a **peer dependency**. Always pin it to the
75
+ > version shown above to avoid conflicts between HOT components and
76
+ > WebAwesome internals.
86
77
 
87
- ### Install HOT Components
78
+ ---
88
79
 
89
- ```bash
90
- pnpm install "@hotosm/ui"
80
+ ## Loading Styles
81
+
82
+ Two CSS files are published. Choose the one that fits your setup.
83
+
84
+ ### Option A — Bundled (recommended for simplicity)
85
+
86
+ A single self-contained file with WebAwesome base styles + HOT theme
87
+ already inlined. Nothing else to load.
88
+
89
+ ```html
90
+ <link rel="stylesheet"
91
+ href="https://cdn.jsdelivr.net/npm/@hotosm/ui@0.6.1/dist/style.css">
92
+ ```
93
+
94
+ Or from a bundler:
95
+
96
+ ```js
97
+ import '@hotosm/ui/dist/style.css';
91
98
  ```
92
99
 
93
- ### Configure The Styles
100
+ ### Option B — Split / CDN-optimised (recommended for multi-tool caching)
101
+
102
+ If you run several HOT tools (FMTM, Tasking Manager, etc.) and want
103
+ the browser to **cache WebAwesome CSS once** across all of them, load
104
+ WebAwesome from CDN separately and use the slim HOT-only stylesheet:
94
105
 
95
- In your `index.html` or equivalent frontend root, add the following classes
96
- to your `<html>` block:
106
+ ```html
107
+ <!-- WebAwesome CSS — shared across all HOT tools via browser cache -->
108
+ <link rel="stylesheet"
109
+ href="https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.2.1/dist/styles/native.css">
110
+ <link rel="stylesheet"
111
+ href="https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.2.1/dist/styles/utilities.css">
112
+ <link rel="stylesheet"
113
+ href="https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.2.1/dist/styles/themes/default.css">
114
+
115
+ <!-- HOT theme only (fonts + design tokens + WebAwesome overrides) -->
116
+ <link rel="stylesheet"
117
+ href="https://cdn.jsdelivr.net/npm/@hotosm/ui@0.6.1/dist/style-core.css">
118
+ ```
97
119
 
98
- ```html
99
- <!DOCTYPE html>
100
- <html class="wa-theme-default wa-palette-hotosm wa-brand-red wa-neutral-gray
101
- wa-success-cyan wa-warning-yellow wa-danger-orange">
102
- <head>
103
- xxx
104
- </head>
105
- <body>
106
- xxx
107
- </body>
108
- </html>
109
- ```
120
+ Or from a bundler:
121
+
122
+ ```js
123
+ // WebAwesome (resolve from node_modules)
124
+ import '@awesome.me/webawesome/dist/styles/native.css';
125
+ import '@awesome.me/webawesome/dist/styles/utilities.css';
126
+ import '@awesome.me/webawesome/dist/styles/themes/default.css';
127
+
128
+ // HOT theme only
129
+ import '@hotosm/ui/dist/style-core.css';
130
+ ```
131
+
132
+ | File | Size | Contains |
133
+ | --- | --- | --- |
134
+ | `style.css` | ~105 KB | WebAwesome + fonts + HOT theme (everything) |
135
+ | `style-core.css` | ~21 KB | Fonts + HOT theme only (no WebAwesome) |
136
+
137
+ > [!TIP]
138
+ > **Which should I pick?**
139
+ >
140
+ > - Building a single standalone app? Use **Option A** — zero config.
141
+ > - Running multiple HOT tools on the same domain or expecting users to
142
+ > navigate between them? Use **Option B** — the ~84 KB of shared
143
+ > WebAwesome CSS is fetched once and cached by the browser.
144
+
145
+ ---
146
+
147
+ ## HTML Setup
148
+
149
+ Add the required WebAwesome classes to your `<html>` element:
150
+
151
+ ```html
152
+ <!DOCTYPE html>
153
+ <html class="wa-theme-default wa-palette-hotosm">
154
+ <head>...</head>
155
+ <body>...</body>
156
+ </html>
157
+ ```
110
158
 
111
159
  > [!IMPORTANT]
112
- > These classes determine the colour usage for different component variants,
113
- > and probably should not be changed!
160
+ > These classes activate the HOT colour palette and light theme for every
161
+ > WebAwesome component on the page. Do not remove them.
114
162
 
115
- And import the required styles in your `main.ts` or equivalent (we import from
116
- package rather than CDN, to allow the bundler to work its CSS tree-shaking
117
- magic).
163
+ ---
118
164
 
119
- ```js
120
- import '@hotosm/ui/dist/style.css';
121
- ```
165
+ ## Using Components
122
166
 
123
- If you wish to use any of the variables in `hot.css` manually, you can reference
124
- them as variables like so:
167
+ ### Via Bundler (Vite, Webpack, etc.)
125
168
 
126
- ```css
127
- /* In your CSS file */
128
- some-param: var(--hot-some-param);
129
- /* See all variables in the `theme/hot.css` file */
130
- ```
169
+ Import individual components — your bundler will tree-shake the rest:
131
170
 
132
- ### Use The Components
171
+ ```js
172
+ import '@hotosm/ui/dist/components/header/header.js';
173
+ ```
133
174
 
134
- #### Via Bundler
175
+ ```html
176
+ <hot-header title="My App"></hot-header>
177
+ ```
135
178
 
136
- Import each component individually into your code:
179
+ ### Via CDN / Plain HTML / HTMX
180
+
181
+ The recommended approach for HTMX and plain-HTML apps loads WebAwesome
182
+ styles and components from CDN so the browser can cache them once across
183
+ all HOT tools (Option B from the styles section above):
184
+
185
+ ```html
186
+ <!DOCTYPE html>
187
+ <html class="wa-theme-default wa-palette-hotosm">
188
+ <head>
189
+ <!-- WebAwesome CSS — cached once across all HOT tools at this WA version -->
190
+ <link rel="stylesheet"
191
+ href="https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.2.1/dist/styles/native.css">
192
+ <link rel="stylesheet"
193
+ href="https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.2.1/dist/styles/utilities.css">
194
+ <link rel="stylesheet"
195
+ href="https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.2.1/dist/styles/themes/default.css">
196
+
197
+ <!-- HOT UI theme (fonts + HOT design tokens + WebAwesome overrides, ~21 KB) -->
198
+ <link rel="stylesheet"
199
+ href="https://cdn.jsdelivr.net/npm/@hotosm/ui@0.6.1/dist/style-core.css">
200
+
201
+ <!-- Import map: resolves WebAwesome bare-module specifiers
202
+ inside hotosm-ui.js -->
203
+ <!-- WA components load lazily from CDN only when first used;
204
+ no separate loader needed -->
205
+ <script type="importmap">
206
+ {
207
+ "imports": {
208
+ "@awesome.me/webawesome/dist/components/":
209
+ "https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.2.1/dist-cdn/components/"
210
+ }
211
+ }
212
+ </script>
213
+
214
+ <!-- HOT UI web components -->
215
+ <script type="module"
216
+ src="https://cdn.jsdelivr.net/npm/@hotosm/ui@0.6.1/dist/hotosm-ui.js">
217
+ </script>
218
+ </head>
219
+
220
+ <body>
221
+ <hot-header id="hdr" title="My App" size="small" show-login></hot-header>
137
222
 
138
- ```html
139
223
  <script>
140
- import '@hotosm/ui/dist/components/header/header.js';
224
+ // Boolean props default to false.
225
+ // Include the attribute to make it true.
226
+ const hdr = document.getElementById('hdr');
227
+ hdr.drawer = true; // enable the hamburger drawer
228
+ hdr.borderBottom = true; // enable bottom border
141
229
  </script>
230
+ </body>
231
+ </html>
232
+ ```
142
233
 
143
- <hot-header
144
- param1=""
145
- param2=""
146
- >
147
- </hot-header>
148
- ```
149
-
150
- #### Via CDN
151
-
152
- If you are working directly in HTML, or other ways without a configured
153
- bundler, you can import all the components as a bundle, as use them like so:
154
-
155
- ```html
156
- <!-- The importmap is required to resolve @awesome.me/webawesome
157
- imports in hotosm/ui -->
158
- <!-- It's also vital to import from dist-cdn to avoid
159
- needing to import subdependencies for webawesome -->
160
- <head>
161
- <script type="importmap">
162
- {
163
- "imports": {
164
- "@awesome.me/webawesome/dist/components/": "https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.0.0/dist-cdn/components/"
165
- }
166
- }
167
- </script>
168
- <script
169
- type="module"
170
- src="https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.0.0/dist-cdn/webawesome.loader.js"
171
- ></script>
172
- <script
173
- type="module"
174
- src="https://cdn.jsdelivr.net/npm/@hotosm/ui@0.4.0/dist/hotosm-ui.js"
175
- ></script>
176
- </head>
177
-
178
- <body>
179
- <hot-header title="Test App" size="small" show-login="false"></hot-header>
180
- </body>
181
- ```
182
-
183
- #### React
184
-
185
- Import in the same way as the bundler example above, except events
186
- are bound to slightly differently:
187
-
188
- ```jsx
189
- <hot-header
190
- title="Test App"
191
- size="small"
192
- showLogin="false"
193
- onLogin={() => {
194
- console.log('handler');
195
- }}
196
- ></hot-header>
197
- ```
198
-
199
- ### Component Guides
200
-
201
- - Header: see [`/header.md`](/header.md) for detailed integration, styling, and
202
- framework examples.
203
-
204
- ### How to contribute
205
-
206
- - Clone the project `git clone git@github.com:hotosm/ui.git`
207
- - Install dependencies `pnpm install`
208
- - Run the storybook `pnpm run dev`
209
- - Write code!
210
-
211
- For **styling**, check `/theme`:
212
-
213
- - `hot.css` has a HOT theme, used across HOT components.
214
- - `hot-wa.css` has a WebAwesome theme, re-defining style variables.
215
-
216
- ### License
217
-
218
- HOT UI is free and open source software! you may use any HOT UI project under the
219
- terms of the GNU Affero General Public License (AGPL) Version 3.
234
+ > [!TIP]
235
+ > If you need only a single self-contained stylesheet instead of the three
236
+ > WA links above, you can use Option A (`style.css`) — but then the ~84 KB
237
+ > of WebAwesome CSS is bundled into the HOT package and cannot be shared
238
+ > across tools as a single cached resource.
239
+
240
+ ### React
241
+
242
+ Web Components work in React with a small caveat — use `ref` callbacks
243
+ for custom events if React's synthetic event system doesn't forward them:
244
+
245
+ ```jsx
246
+ import '@hotosm/ui/dist/components/header/header.js';
247
+
248
+ function App() {
249
+ return (
250
+ <hot-header
251
+ title="My App"
252
+ ref={(el) => {
253
+ if (el) el.addEventListener('login', () => console.log('logged in'));
254
+ }}
255
+ />
256
+ );
257
+ }
258
+ ```
259
+
260
+ ---
261
+
262
+ ## Using HOT Design Tokens
263
+
264
+ The HOT theme exposes CSS custom properties you can reference in your
265
+ own stylesheets:
266
+
267
+ ```css
268
+ .my-card {
269
+ background: var(--hot-color-primary-50);
270
+ color: var(--hot-color-neutral-900);
271
+ font-family: var(--hot-font-sans);
272
+ padding: var(--hot-spacing-medium);
273
+ border-radius: var(--hot-border-radius-large);
274
+ }
275
+ ```
276
+
277
+ See all available tokens in
278
+ [`src/themes/hot.css`](src/themes/hot.css).
279
+
280
+ ---
281
+
282
+ ## Component Guides
283
+
284
+ - **Header:** see [`header.md`](header.md) for detailed integration,
285
+ styling, and framework examples.
286
+
287
+ ---
288
+
289
+ ## Contributing
290
+
291
+ ```bash
292
+ git clone git@github.com:hotosm/ui.git
293
+ cd ui
294
+ pnpm install
295
+ pnpm run dev # starts Storybook on localhost:3001
296
+ ```
297
+
298
+ **Styling files** (under `src/themes/`):
299
+
300
+ | File | Purpose |
301
+ | --- | --- |
302
+ | `hot.css` | HOT design tokens (colours, typography, spacing) |
303
+ | `hot-wa.css` | WebAwesome variable overrides to apply the HOT palette |
304
+
305
+ ---
306
+
307
+ ## License
308
+
309
+ HOT UI is free and open source software. You may use any HOT UI project
310
+ under the terms of the
311
+ [GNU Affero General Public License (AGPL) Version 3](LICENSE.md).
@@ -45,7 +45,7 @@ import{a as o}from"./chunk.QABMDRWR.js";var e=o`
45
45
  }
46
46
 
47
47
  .dropzone:focus {
48
- outline: 2px solid var(--hot-color-red-600);
48
+ outline: 2px solid var(--wa-color-focus);
49
49
  outline-offset: 2px;
50
50
  }
51
51
 
@@ -54,13 +54,13 @@ import{a as o}from"./chunk.QABMDRWR.js";var e=o`
54
54
  }
55
55
 
56
56
  .dropzone:focus-visible {
57
- outline: 2px solid var(--hot-color-red-600);
57
+ outline: 2px solid var(--wa-color-focus);
58
58
  outline-offset: 2px;
59
59
  }
60
60
 
61
61
  .dropzone--dragging {
62
- border-color: var(--hot-color-red-500);
63
- background-color: var(--hot-color-red-100);
62
+ border-color: var(--hot-color-primary-500);
63
+ background-color: var(--hot-color-primary-100);
64
64
  border-width: 3px;
65
65
  }
66
66
 
@@ -96,11 +96,11 @@ import{a as o}from"./chunk.QABMDRWR.js";var e=o`
96
96
  }
97
97
 
98
98
  .dropzone:hover:not(.dropzone--disabled) .dropzone-icon {
99
- color: var(--hot-color-red-500);
99
+ color: var(--hot-color-primary-500);
100
100
  }
101
101
 
102
102
  .dropzone--dragging .dropzone-icon {
103
- color: var(--hot-color-red-600);
103
+ color: var(--hot-color-primary-600);
104
104
  }
105
105
 
106
106
  .dropzone-cta {
@@ -110,7 +110,7 @@ import{a as o}from"./chunk.QABMDRWR.js";var e=o`
110
110
 
111
111
  .dropzone-text {
112
112
  font-size: var(--hot-font-size-small);
113
- font-weight: 500;
113
+ font-weight: var(--hot-font-weight-semibold);
114
114
  color: var(--hot-color-neutral-700);
115
115
  text-align: center;
116
116
  }
@@ -152,15 +152,15 @@ import{a as o}from"./chunk.QABMDRWR.js";var e=o`
152
152
  gap: var(--hot-spacing-x-small);
153
153
  margin-top: var(--hot-spacing-small);
154
154
  padding: var(--hot-spacing-small);
155
- background-color: var(--hot-color-red-50);
156
- border: 1px solid var(--hot-color-red-200);
155
+ background-color: var(--hot-color-danger-50);
156
+ border: 1px solid var(--hot-color-danger-200);
157
157
  border-radius: var(--hot-border-radius-small);
158
- color: var(--hot-color-red-700);
158
+ color: var(--hot-color-danger-700);
159
159
  font-size: var(--hot-font-size-small);
160
160
  }
161
161
 
162
162
  .error-message wa-icon {
163
- color: var(--hot-color-red-600);
163
+ color: var(--hot-color-danger-600);
164
164
  font-size: var(--hot-font-size-medium);
165
165
  }
166
166
 
@@ -1 +1 @@
1
- import{b as e}from"./chunk.7PROWJNJ.js";var a=e;customElements.get("hot-header")||customElements.define("hot-header",e);export{a};
1
+ import{b as e}from"./chunk.XU6UFL27.js";var a=e;customElements.get("hot-header")||customElements.define("hot-header",e);export{a};
@@ -1 +1 @@
1
- import{b as o}from"./chunk.CQO3GWTI.js";var t=o;customElements.get("hotosm-tool-menu")||customElements.define("hotosm-tool-menu",o);export{t as a};
1
+ import{b as o}from"./chunk.P6GWPFCT.js";var t=o;customElements.get("hotosm-tool-menu")||customElements.define("hotosm-tool-menu",o);export{t as a};
@@ -1,4 +1,4 @@
1
- import{a as l}from"./chunk.KO4EOD3I.js";import{a as d}from"./chunk.MZOQNTPX.js";import{a as r}from"./chunk.ZETV7TDG.js";import{d as o,f as c}from"./chunk.QABMDRWR.js";import{d as s,e as n,f as a,g as i}from"./chunk.N2W26RCT.js";import"@awesome.me/webawesome/dist/components/callout/callout.js";import"@awesome.me/webawesome/dist/components/icon/icon.js";import"@awesome.me/webawesome/dist/components/button/button.js";l();var u,g,p,b,h,m,e=class extends c{constructor(){super(...arguments);this.name="hot-consent";a(this,u,"");a(this,g,!0);a(this,p,"About the information we collect");a(this,b,"We use cookies and similar technologies to recognize and analyze your visits, and measure traffic usage and activity.");a(this,h,"I Agree");a(this,m,"I Do Not Agree")}get consentId(){return n(this,u)}set consentId(t){i(this,u,t)}get isOpen(){return n(this,g)}set isOpen(t){i(this,g,t)}get title(){return n(this,p)}set title(t){i(this,p,t)}get message(){return n(this,b)}set message(t){i(this,b,t)}get agreeLabel(){return n(this,h)}set agreeLabel(t){i(this,h,t)}get notAgreeLabel(){return n(this,m)}set notAgreeLabel(t){i(this,m,t)}render(){return this.isOpen?o`
1
+ import{a as d}from"./chunk.ZGC6XD6L.js";import{a as o}from"./chunk.ZETV7TDG.js";import{a as l}from"./chunk.KO4EOD3I.js";import{d as r,f as c}from"./chunk.QABMDRWR.js";import{d as s,e as a,f as n,g as i}from"./chunk.N2W26RCT.js";Promise.allSettled([import("@awesome.me/webawesome/dist/components/callout/callout.js"),import("@awesome.me/webawesome/dist/components/icon/icon.js"),import("@awesome.me/webawesome/dist/components/button/button.js")]);l();var u,g,p,b,m,h,e=class extends c{constructor(){super(...arguments);this.name="hot-consent";n(this,u,"");n(this,g,!1);n(this,p,"About the information we collect");n(this,b,"We use cookies and similar technologies to recognize and analyze your visits, and measure traffic usage and activity.");n(this,m,"I Agree");n(this,h,"I Do Not Agree")}get consentId(){return a(this,u)}set consentId(t){i(this,u,t)}get isOpen(){return a(this,g)}set isOpen(t){i(this,g,t)}get title(){return a(this,p)}set title(t){i(this,p,t)}get message(){return a(this,b)}set message(t){i(this,b,t)}get agreeLabel(){return a(this,m)}set agreeLabel(t){i(this,m,t)}get notAgreeLabel(){return a(this,h)}set notAgreeLabel(t){i(this,h,t)}render(){return this.isOpen?r`
2
2
  <div class="consent-overlay">
3
3
  <div class="consent-container">
4
4
  <wa-callout variant="brand" appearance="outlined filled" size="large" class="consent-callout">
@@ -33,4 +33,4 @@ import{a as l}from"./chunk.KO4EOD3I.js";import{a as d}from"./chunk.MZOQNTPX.js";
33
33
  </wa-callout>
34
34
  </div>
35
35
  </div>
36
- `:null}_setAgree(t){this.isOpen=!1,localStorage.setItem(`${this.consentId}-consent-agree`,"true"),this.dispatchEvent(new Event("agree",{bubbles:!0,composed:!0}))}_setDisagree(t){this.isOpen=!1,localStorage.setItem(`${this.consentId}-consent-agree`,"false"),this.dispatchEvent(new Event("disagree",{bubbles:!0,composed:!0}))}connectedCallback(){super.connectedCallback();let t=localStorage.getItem(`${this.consentId}-consent-agree`);if(t==="false"){this.isOpen=!1;return}t==="true"&&(this.isOpen=!1)}};u=new WeakMap,g=new WeakMap,p=new WeakMap,b=new WeakMap,h=new WeakMap,m=new WeakMap,e.styles=[d],s([r({type:String,attribute:"consent-id"})],e.prototype,"consentId",1),s([r({type:Boolean})],e.prototype,"isOpen",1),s([r({type:String})],e.prototype,"title",1),s([r({type:String})],e.prototype,"message",1),s([r({type:String,attribute:"agree-label"})],e.prototype,"agreeLabel",1),s([r({type:String,attribute:"not-agree-label"})],e.prototype,"notAgreeLabel",1);var k=e;export{e as a,k as b};
36
+ `:null}_setAgree(t){this.isOpen=!1,localStorage.setItem(`${this.consentId}-consent-agree`,"true"),this.dispatchEvent(new Event("agree",{bubbles:!0,composed:!0}))}_setDisagree(t){this.isOpen=!1,localStorage.setItem(`${this.consentId}-consent-agree`,"false"),this.dispatchEvent(new Event("disagree",{bubbles:!0,composed:!0}))}connectedCallback(){super.connectedCallback();let t=localStorage.getItem(`${this.consentId}-consent-agree`);if(t==="false"){this.isOpen=!1;return}t==="true"&&(this.isOpen=!1)}};u=new WeakMap,g=new WeakMap,p=new WeakMap,b=new WeakMap,m=new WeakMap,h=new WeakMap,e.styles=[d],s([o({type:String,attribute:"consent-id"})],e.prototype,"consentId",1),s([o({type:Boolean,attribute:"is-open"})],e.prototype,"isOpen",1),s([o({type:String})],e.prototype,"title",1),s([o({type:String})],e.prototype,"message",1),s([o({type:String,attribute:"agree-label"})],e.prototype,"agreeLabel",1),s([o({type:String,attribute:"not-agree-label"})],e.prototype,"notAgreeLabel",1);var E=e;export{e as a,E as b};
@@ -1 +1 @@
1
- import{b as e}from"./chunk.ORZ5STBX.js";var n=e;customElements.get("hot-consent")||customElements.define("hot-consent",e);export{n as a};
1
+ import{b as e}from"./chunk.6BGQ256H.js";var n=e;customElements.get("hot-consent")||customElements.define("hot-consent",e);export{n as a};
@@ -1 +1 @@
1
- import{b as o}from"./chunk.BD4Q32VT.js";var t=o;customElements.get("hot-logo")||customElements.define("hot-logo",o);export{t as a};
1
+ import{b as o}from"./chunk.LVCDAVRU.js";var t=o;customElements.get("hot-logo")||customElements.define("hot-logo",o);export{t as a};
@@ -1 +1 @@
1
- import{b as e}from"./chunk.WTTPHBL3.js";var t=e;customElements.get("hot-file-input-dropzone")||customElements.define("hot-file-input-dropzone",e);export{t as a};
1
+ import{b as e}from"./chunk.CNUZFRRF.js";var t=e;customElements.get("hot-file-input-dropzone")||customElements.define("hot-file-input-dropzone",e);export{t as a};
@@ -0,0 +1,105 @@
1
+ import{a as M}from"./chunk.252GL6HT.js";import{a as f,b as m,c as z}from"./chunk.ZETV7TDG.js";import{d as h,e as x,f as F}from"./chunk.QABMDRWR.js";import{d as n,e as o,f as d,g as c}from"./chunk.N2W26RCT.js";var E={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},y=l=>(...a)=>({_$litDirective$:l,values:a}),$=class{constructor(a){}get _$AU(){return this._$AM._$AU}_$AT(a,e,i){this._$Ct=a,this._$AM=e,this._$Ci=i}_$AS(a,e){return this.update(a,e)}update(a,e){return this.render(...e)}};var _=y(class extends ${constructor(l){var a;if(super(l),l.type!==E.ATTRIBUTE||l.name!=="class"||((a=l.strings)==null?void 0:a.length)>2)throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute.")}render(l){return" "+Object.keys(l).filter(a=>l[a]).join(" ")+" "}update(l,[a]){var i,s;if(this.st===void 0){this.st=new Set,l.strings!==void 0&&(this.nt=new Set(l.strings.join(" ").split(/\s/).filter(t=>t!=="")));for(let t in a)a[t]&&!((i=this.nt)!=null&&i.has(t))&&this.st.add(t);return this.render(a)}let e=l.element.classList;for(let t of this.st)t in a||(e.remove(t),this.st.delete(t));for(let t in a){let p=!!a[t];p===this.st.has(t)||(s=this.nt)!=null&&s.has(t)||(p?(e.add(t),this.st.add(t)):(e.remove(t),this.st.delete(t)))}return x}});Promise.allSettled([import("@awesome.me/webawesome/dist/components/icon/icon.js"),import("@awesome.me/webawesome/dist/components/divider/divider.js")]);var S,T,C,D,P,A,B,L,k,W,I,O,r=class extends F{constructor(){super(...arguments);this.name="hot-file-input-dropzone";d(this,S,!1);d(this,T,"");d(this,C,0);d(this,D,!1);d(this,P,!1);d(this,A,"");d(this,B,"traditional");d(this,L,!1);d(this,k,[]);d(this,W,"");d(this,I,"");d(this,O)}get multiple(){return o(this,S)}set multiple(e){c(this,S,e)}get accept(){return o(this,T)}set accept(e){c(this,T,e)}get maxSize(){return o(this,C)}set maxSize(e){c(this,C,e)}get showPreview(){return o(this,D)}set showPreview(e){c(this,D,e)}get disabled(){return o(this,P)}set disabled(e){c(this,P,e)}get label(){return o(this,A)}set label(e){c(this,A,e)}get variant(){return o(this,B)}set variant(e){c(this,B,e)}get isDragging(){return o(this,L)}set isDragging(e){c(this,L,e)}get selectedFiles(){return o(this,k)}set selectedFiles(e){c(this,k,e)}get errorMessage(){return o(this,W)}set errorMessage(e){c(this,W,e)}get statusMessage(){return o(this,I)}set statusMessage(e){c(this,I,e)}get fileInput(){return o(this,O)}set fileInput(e){c(this,O,e)}_generateId(){return`file-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}_handleDragOver(e){e.preventDefault(),e.stopPropagation(),this.disabled||(this.isDragging=!0)}_handleDragLeave(e){e.preventDefault(),e.stopPropagation(),this.isDragging=!1}_handleDrop(e){var s;if(e.preventDefault(),e.stopPropagation(),this.isDragging=!1,this.disabled)return;let i=Array.from(((s=e.dataTransfer)==null?void 0:s.files)||[]);this._processFiles(i)}_handleClick(){this.disabled||this.fileInput.click()}_handleKeyDown(e){!this.disabled&&(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),this.fileInput.click())}_handleFileInputChange(e){let i=e.target,s=Array.from(i.files||[]);this._processFiles(s)}_processFiles(e){if(this.errorMessage="",!this.multiple&&e.length>1){this.errorMessage="Only one file can be selected";return}if(this.accept){let t=this.accept.split(",").map(u=>u.trim().toLowerCase()),p=e.filter(u=>{let b=u.name.toLowerCase(),g=u.type.toLowerCase();return!t.some(v=>{if(v.startsWith("."))return b.endsWith(v);if(v.endsWith("/*")){let w=v.split("/")[0];if(g)return g.startsWith(w+"/");let j=b.substring(b.lastIndexOf("."));return this._getFileIcon(j).includes(w)}return g?g===v:!1})});if(p.length>0){this.errorMessage=`Invalid file type(s): ${p.map(u=>u.name).join(", ")}`;return}}if(this.maxSize>0){let t=e.filter(p=>p.size>this.maxSize);if(t.length>0){this.errorMessage=`File(s) exceed maximum size of ${this._formatFileSize(this.maxSize)}: ${t.map(p=>p.name).join(", ")}`;return}}let i=e.map(t=>({file:t,id:this._generateId()}));this.multiple?this.selectedFiles=[...i,...this.selectedFiles]:this.selectedFiles=i,this.dispatchEvent(new CustomEvent("hot-file-change",{detail:{files:this.selectedFiles.map(t=>t.file)},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("hot-files-selected",{detail:{files:i.map(t=>t.file),allFiles:this.selectedFiles.map(t=>t.file)},bubbles:!0,composed:!0}));let s=i.length;this.statusMessage=`${s} ${s===1?"file":"files"} selected: ${i.map(t=>t.file.name).join(", ")}`}_removeFile(e){let i=this.selectedFiles.find(s=>s.id===e);this.selectedFiles=this.selectedFiles.filter(s=>s.id!==e),this.fileInput&&(this.fileInput.value=""),this.dispatchEvent(new CustomEvent("hot-file-change",{detail:{files:this.selectedFiles.map(s=>s.file)},bubbles:!0,composed:!0})),i&&(this.statusMessage=`File removed: ${i.file.name}. ${this.selectedFiles.length} ${this.selectedFiles.length===1?"file":"files"} remaining.`)}_formatFileSize(e){if(e===0)return"0 Bytes";let i=1e3,s=["Bytes","KB","MB","GB"],t=Math.floor(Math.log(e)/Math.log(i)),p=e/Math.pow(i,t);return`${Math.round(p*10)/10} ${s[t]}`}_getFileIcon(e){return e.startsWith("image/")?"file-image":e.startsWith("video/")?"file-video":e.startsWith("audio/")?"file-audio":e==="application/pdf"?"file-pdf":e.includes("word")?"file-word":e.includes("sheet")||e.includes("excel")?"file-excel":e.includes("zip")||e.includes("rar")||e.includes("7z")?"file-archive":e.includes("text")?"file-text":"file"}clearFiles(){this.selectedFiles=[],this.errorMessage="",this.fileInput&&(this.fileInput.value="")}getFiles(){return this.selectedFiles.map(e=>e.file)}render(){let e={dropzone:!0,"dropzone--dragging":this.isDragging,"dropzone--disabled":this.disabled,"dropzone--has-files":this.selectedFiles.length>0,"dropzone--compact":this.variant==="compact"},i=this.variant==="compact";return h`
2
+ <div class="file-input-dropzone">
3
+ ${this.label&&this.variant==="traditional"?h`<label class="label" id="dropzone-label">${this.label}</label>`:""}
4
+ ${this.variant==="traditional"?h`<wa-divider></wa-divider>`:""}
5
+
6
+ <div
7
+ class=${_(e)}
8
+ role="button"
9
+ tabindex=${this.disabled?"-1":"0"}
10
+ aria-disabled=${this.disabled}
11
+ aria-label=${this.label||"File upload"}
12
+ aria-describedby="dropzone-description${this.accept||this.maxSize?" dropzone-hints":""}"
13
+ @dragover=${this._handleDragOver}
14
+ @dragleave=${this._handleDragLeave}
15
+ @drop=${this._handleDrop}
16
+ @click=${this._handleClick}
17
+ @keydown=${this._handleKeyDown}
18
+ >
19
+ <input
20
+ type="file"
21
+ class="file-uploader"
22
+ ?multiple=${this.multiple}
23
+ accept=${this.accept}
24
+ ?disabled=${this.disabled}
25
+ @change=${this._handleFileInputChange}
26
+ aria-hidden="true"
27
+ tabindex="-1"
28
+ />
29
+
30
+ <div class="dropzone-content">
31
+ <wa-icon
32
+ name="${i?"arrow-up-from-bracket":"cloud-arrow-up"}"
33
+ class="dropzone-icon"
34
+ aria-hidden="true"
35
+ ></wa-icon>
36
+ <div class="dropzone-text">
37
+ ${i?h`<div class="compact-text" id="dropzone-description">
38
+ ${this.label}
39
+ </div>`:this.isDragging?h`<div id="dropzone-description">
40
+ Drop ${this.multiple?"files":"file"} here
41
+ </div>`:h`
42
+ <div class="dropzone-cta" id="dropzone-description">
43
+ <div>
44
+ Drop ${this.multiple?"files":"file"} here or&nbsp;
45
+ </div>
46
+ <div class="browse">browse</div>
47
+ </div>
48
+ ${this.accept||this.maxSize?h`<div id="dropzone-hints">
49
+ ${this.accept?h`<div class="dropzone-accept">
50
+ ${this.accept.split(",").join(", ")} only
51
+ </div>`:""}
52
+ ${this.maxSize?h`<div class="dropzone-maxsize">
53
+ Max size: ${this._formatFileSize(this.maxSize)}
54
+ </div>`:""}
55
+ </div>`:""}
56
+ `}
57
+ </div>
58
+ </div>
59
+ </div>
60
+ ${this.errorMessage?h`
61
+ <div class="error-message" role="alert">
62
+ <wa-icon name="exclamation-circle"></wa-icon>
63
+ ${this.errorMessage}
64
+ </div>
65
+ `:""}
66
+ ${this.showPreview&&this.selectedFiles.length>0?h`
67
+ <div class="file-preview-list">
68
+ ${this.selectedFiles.map(({file:s,id:t})=>h`
69
+ <hot-list-card
70
+ title=${s.name}
71
+ subtitle=${this._formatFileSize(s.size)}
72
+ icon=${this._getFileIcon(s.type)}
73
+ itemId=${t}
74
+ @hot-remove=${()=>this._removeFile(t)}
75
+ ></hot-list-card>
76
+ `)}
77
+ </div>
78
+ `:""}
79
+
80
+ <div
81
+ class="sr-only"
82
+ role="status"
83
+ aria-live="polite"
84
+ aria-atomic="true"
85
+ >
86
+ ${this.statusMessage}
87
+ </div>
88
+ </div>
89
+ `}};S=new WeakMap,T=new WeakMap,C=new WeakMap,D=new WeakMap,P=new WeakMap,A=new WeakMap,B=new WeakMap,L=new WeakMap,k=new WeakMap,W=new WeakMap,I=new WeakMap,O=new WeakMap,r.styles=[M],n([f({type:Boolean})],r.prototype,"multiple",1),n([f({type:String})],r.prototype,"accept",1),n([f({type:Number})],r.prototype,"maxSize",1),n([f({type:Boolean,attribute:"show-preview"})],r.prototype,"showPreview",1),n([f({type:Boolean})],r.prototype,"disabled",1),n([f({type:String})],r.prototype,"label",1),n([f({type:String})],r.prototype,"variant",1),n([m()],r.prototype,"isDragging",1),n([m()],r.prototype,"selectedFiles",1),n([m()],r.prototype,"errorMessage",1),n([m()],r.prototype,"statusMessage",1),n([z('input[type="file"]')],r.prototype,"fileInput",1);var Z=r;export{r as a,Z as b};
90
+ /*! Bundled license information:
91
+
92
+ lit-html/directive.js:
93
+ (**
94
+ * @license
95
+ * Copyright 2017 Google LLC
96
+ * SPDX-License-Identifier: BSD-3-Clause
97
+ *)
98
+
99
+ lit-html/directives/class-map.js:
100
+ (**
101
+ * @license
102
+ * Copyright 2018 Google LLC
103
+ * SPDX-License-Identifier: BSD-3-Clause
104
+ *)
105
+ */