@hotosm/ui 0.7.0 → 0.8.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 (27) hide show
  1. package/README.md +12 -9
  2. package/dist/chunks/{chunk.CNUZFRRF.js → chunk.6JUW2IZJ.js} +1 -1
  3. package/dist/chunks/{chunk.XU6UFL27.js → chunk.BMD7HOGS.js} +140 -49
  4. package/dist/chunks/chunk.F26WEVPO.js +526 -0
  5. package/dist/chunks/{chunk.6BGQ256H.js → chunk.LVC64FO7.js} +1 -1
  6. package/dist/chunks/{chunk.7JIKOYG6.js → chunk.M3LK72JN.js} +1 -1
  7. package/dist/chunks/{chunk.2Y7OBKRQ.js → chunk.MYCDEEQF.js} +1 -1
  8. package/dist/chunks/{chunk.APYFF2XE.js → chunk.N5KXL4J6.js} +1 -1
  9. package/dist/chunks/{chunk.LVCDAVRU.js → chunk.R44PTHOJ.js} +1 -1
  10. package/dist/chunks/{chunk.BVHLTKMC.js → chunk.WELXILIP.js} +1 -1
  11. package/dist/chunks/chunk.ZKUACKKG.js +14 -0
  12. package/dist/components/consent/consent.component.js +1 -1
  13. package/dist/components/consent/consent.js +1 -1
  14. package/dist/components/file-input-dropzone/file-input-dropzone.component.js +1 -1
  15. package/dist/components/file-input-dropzone/file-input-dropzone.js +1 -1
  16. package/dist/components/header/header.component.d.ts +31 -2
  17. package/dist/components/header/header.component.js +1 -1
  18. package/dist/components/header/header.js +1 -1
  19. package/dist/components/header/header.styles.js +1 -1
  20. package/dist/components/logo/logo.component.js +1 -1
  21. package/dist/components/logo/logo.js +1 -1
  22. package/dist/components/logo/logo.styles.js +1 -1
  23. package/dist/hotosm-ui.js +1 -1
  24. package/dist/themes/hot-wa.css +9 -9
  25. package/package.json +1 -1
  26. package/dist/chunks/chunk.FDQFFQX3.js +0 -166
  27. package/dist/chunks/chunk.PBBH42B6.js +0 -6
package/README.md CHANGED
@@ -11,6 +11,9 @@
11
11
  <a href="https://github.com/hotosm/ui/actions/workflows/publish.yml" target="_blank">
12
12
  <img src="https://github.com/hotosm/ui/actions/workflows/publish.yml/badge.svg?event=release" alt="Publish">
13
13
  </a>
14
+ <a href="https://github.com/hotosm/ui/actions/workflows/playwright.yml" target="_blank">
15
+ <img src="https://github.com/hotosm/ui/actions/workflows/playwright.yml/badge.svg?branch=main" alt="Tests">
16
+ </a>
14
17
  <a href="https://github.com/hotosm/ui/actions/workflows/cdn_deploy.yml" target="_blank">
15
18
  <img src="https://github.com/hotosm/ui/actions/workflows/cdn_deploy.yml/badge.svg?branch=main" alt="CDN Deploy">
16
19
  </a>
@@ -81,7 +84,7 @@ pnpm install @hotosm/ui @awesome.me/webawesome@3.2.1
81
84
 
82
85
  Two CSS files are published. Choose the one that fits your setup.
83
86
 
84
- ### Option A Bundled (recommended for simplicity)
87
+ ### Option A - Bundled (recommended for simplicity)
85
88
 
86
89
  A single self-contained file with WebAwesome base styles + HOT theme
87
90
  already inlined. Nothing else to load.
@@ -97,14 +100,14 @@ Or from a bundler:
97
100
  import '@hotosm/ui/dist/style.css';
98
101
  ```
99
102
 
100
- ### Option B Split / CDN-optimised (recommended for multi-tool caching)
103
+ ### Option B - Split / CDN-optimised (recommended for multi-tool caching)
101
104
 
102
105
  If you run several HOT tools (FMTM, Tasking Manager, etc.) and want
103
106
  the browser to **cache WebAwesome CSS once** across all of them, load
104
107
  WebAwesome from CDN separately and use the slim HOT-only stylesheet:
105
108
 
106
109
  ```html
107
- <!-- WebAwesome CSS shared across all HOT tools via browser cache -->
110
+ <!-- WebAwesome CSS - shared across all HOT tools via browser cache -->
108
111
  <link rel="stylesheet"
109
112
  href="https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.2.1/dist/styles/native.css">
110
113
  <link rel="stylesheet"
@@ -137,9 +140,9 @@ import '@hotosm/ui/dist/style-core.css';
137
140
  > [!TIP]
138
141
  > **Which should I pick?**
139
142
  >
140
- > - Building a single standalone app? Use **Option A** zero config.
143
+ > - Building a single standalone app? Use **Option A** - zero config.
141
144
  > - Running multiple HOT tools on the same domain or expecting users to
142
- > navigate between them? Use **Option B** the ~84 KB of shared
145
+ > navigate between them? Use **Option B** - the ~84 KB of shared
143
146
  > WebAwesome CSS is fetched once and cached by the browser.
144
147
 
145
148
  ---
@@ -166,7 +169,7 @@ Add the required WebAwesome classes to your `<html>` element:
166
169
 
167
170
  ### Via Bundler (Vite, Webpack, etc.)
168
171
 
169
- Import individual components your bundler will tree-shake the rest:
172
+ Import individual components - your bundler will tree-shake the rest:
170
173
 
171
174
  ```js
172
175
  import '@hotosm/ui/dist/components/header/header.js';
@@ -186,7 +189,7 @@ all HOT tools (Option B from the styles section above):
186
189
  <!DOCTYPE html>
187
190
  <html class="wa-theme-default wa-palette-hotosm">
188
191
  <head>
189
- <!-- WebAwesome CSS cached once across all HOT tools at this WA version -->
192
+ <!-- WebAwesome CSS - cached once across all HOT tools at this WA version -->
190
193
  <link rel="stylesheet"
191
194
  href="https://cdn.jsdelivr.net/npm/@awesome.me/webawesome@3.2.1/dist/styles/native.css">
192
195
  <link rel="stylesheet"
@@ -233,13 +236,13 @@ all HOT tools (Option B from the styles section above):
233
236
 
234
237
  > [!TIP]
235
238
  > 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
239
+ > WA links above, you can use Option A (`style.css`) - but then the ~84 KB
237
240
  > of WebAwesome CSS is bundled into the HOT package and cannot be shared
238
241
  > across tools as a single cached resource.
239
242
 
240
243
  ### React
241
244
 
242
- Web Components work in React with a small caveat use `ref` callbacks
245
+ Web Components work in React with a small caveat - use `ref` callbacks
243
246
  for custom events if React's synthetic event system doesn't forward them:
244
247
 
245
248
  ```jsx
@@ -1,4 +1,4 @@
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`
1
+ import{a as f,b as m,c as z}from"./chunk.ZETV7TDG.js";import{a as M}from"./chunk.252GL6HT.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
2
  <div class="file-input-dropzone">
3
3
  ${this.label&&this.variant==="traditional"?h`<label class="label" id="dropzone-label">${this.label}</label>`:""}
4
4
  ${this.variant==="traditional"?h`<wa-divider></wa-divider>`:""}