@limetech/lime-elements 39.42.0 → 39.42.2

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.
@@ -0,0 +1 @@
1
+ const t={"image/jpeg":"jpg","image/png":"png"};async function n(n,e){var o;const{fit:i,quality:r}=e,a=(j=n.type,e.type||(Object.prototype.hasOwnProperty.call(t,j)?j:"image/jpeg")),c=null!==(o=e.rename)&&void 0!==o?o:n=>function(n,e){const o=t[e],i=n.lastIndexOf(".");return`${i>0?n.slice(0,i):n}.${o}`}(n,a),s=await async function(t){var n,e;if("function"==typeof globalThis.createImageBitmap)try{return await globalThis.createImageBitmap(t,{imageOrientation:"from-image"})}catch(t){"production"!==(null===(e=null===(n=globalThis.process)||void 0===n?void 0:n.env)||void 0===e?void 0:e.NODE_ENV)&&"undefined"!=typeof console&&"function"==typeof console.debug&&console.debug("createImageBitmap failed, falling back to HTMLImageElement:",t)}return await async function(t){var n;const e=URL.createObjectURL(t);try{const t=new Image;return t.decoding="sync",t.src=e,await(null===(n=t.decode)||void 0===n?void 0:n.call(t).catch((()=>{}))),t.complete||await new Promise(((n,e)=>{const o=()=>{t.removeEventListener("load",i),t.removeEventListener("error",r)},i=()=>{o(),n()},r=t=>{o(),e(t)};t.addEventListener("load",i),t.addEventListener("error",r)})),t}finally{URL.revokeObjectURL(e)}}(t)}(n),l=s.width,u=s.height,{width:d,height:h}=function(t,n,e,o){const i="number"==typeof e&&e>0,r="number"==typeof o&&o>0;return i&&r?{width:e,height:o}:i?{width:e,height:Math.round(e*(n/t))}:r?{width:Math.round(o*(t/n)),height:o}:{width:t,height:n}}(l,u,e.width,e.height),{sx:f,sy:w,sw:g,sh:y,dx:m,dy:p,dw:v,dh:b}=function(t,n,e,o,i){const r=t/n,a=e/o;if("cover"===i){let i,c;return r>a?(c=n,i=n*a):(i=t,c=t/a),{sx:(t-i)/2,sy:(n-c)/2,sw:i,sh:c,dx:0,dy:0,dw:e,dh:o}}let c,s;r>a?(c=e,s=e/r):(s=o,c=o*r);return{sx:0,sy:0,sw:t,sh:n,dx:(e-c)/2,dy:(o-s)/2,dw:c,dh:s}}(l,u,d,h,i),x=function(t,n){if(function(){try{return"function"==typeof globalThis.OffscreenCanvas}catch(t){return!1}}())return new globalThis.OffscreenCanvas(t,n);const e=document.createElement("canvas");return e.width=t,e.height=n,e}(d,h),T=function(t){const n=t.getContext("2d",{alpha:!0});if(!n)throw new Error("2D canvas context not available");return n}(x);var j;T.clearRect(0,0,d,h),T.drawImage(s,f,w,g,y,m,p,v,b);const E=await function(t,n,e){return"convertToBlob"in t?t.convertToBlob({type:n,quality:e}):new Promise(((o,i)=>{t.toBlob((t=>{t?o(t):i(new Error("Failed to create blob from canvas"))}),n,e)}))}(x,a,r),I=c(n.name);return new File([E],I,{type:a})}export{n as r}
@@ -81,6 +81,8 @@ export declare class ProfilePicture {
81
81
  /**
82
82
  * Optional client-side resize before emitting the file.
83
83
  * If provided, the selected image will be resized on the client device.
84
+ * Omitted options fall back to avatar defaults: `image/jpeg`, `quality`
85
+ * `0.85`, and the component's `imageFit`.
84
86
  * :::note
85
87
  * HEIC may not decode in all browsers; when decoding fails, the original
86
88
  * file will be emitted. See the examples for more info.
@@ -3113,7 +3113,7 @@ export namespace Components {
3113
3113
  */
3114
3114
  "required": boolean;
3115
3115
  /**
3116
- * Optional client-side resize before emitting the file. If provided, the selected image will be resized on the client device. :::note HEIC may not decode in all browsers; when decoding fails, the original file will be emitted. See the examples for more info. :::
3116
+ * Optional client-side resize before emitting the file. If provided, the selected image will be resized on the client device. Omitted options fall back to avatar defaults: `image/jpeg`, `quality` `0.85`, and the component's `imageFit`. :::note HEIC may not decode in all browsers; when decoding fails, the original file will be emitted. See the examples for more info. :::
3117
3117
  */
3118
3118
  "resize"?: ResizeOptions;
3119
3119
  /**
@@ -9824,7 +9824,7 @@ declare namespace LocalJSX {
9824
9824
  */
9825
9825
  "required"?: boolean;
9826
9826
  /**
9827
- * Optional client-side resize before emitting the file. If provided, the selected image will be resized on the client device. :::note HEIC may not decode in all browsers; when decoding fails, the original file will be emitted. See the examples for more info. :::
9827
+ * Optional client-side resize before emitting the file. If provided, the selected image will be resized on the client device. Omitted options fall back to avatar defaults: `image/jpeg`, `quality` `0.85`, and the component's `imageFit`. :::note HEIC may not decode in all browsers; when decoding fails, the original file will be emitted. See the examples for more info. :::
9828
9828
  */
9829
9829
  "resize"?: ResizeOptions;
9830
9830
  /**
@@ -12,15 +12,17 @@
12
12
  *
13
13
  * Why resize client-side?
14
14
  * - Faster perceived uploads and lower bandwidth usage
15
- * - Consistent avatar sizes and formats (e.g., JPEG 400x400)
15
+ * - Consistent output sizes and formats (e.g., a 400x400 thumbnail)
16
16
  * - No server-side transformation required for common cases
17
17
  *
18
18
  * Fit strategies
19
- * - `cover` (default): The image is scaled to cover the target rectangle, and
20
- * the excess parts are center-cropped. Good for avatars.
19
+ * - `cover`: The image is scaled to cover the target rectangle, and the excess
20
+ * parts are center-cropped. Good for avatars.
21
21
  * - `contain`: The image is scaled to fit entirely within the target rectangle
22
22
  * without cropping, letterboxing if needed. Good when you must preserve the
23
23
  * entire image.
24
+ * - omitted: scales the whole image to fit without cropping (no pixels are
25
+ * discarded).
24
26
  *
25
27
  * Decoding & EXIF orientation
26
28
  * EXIF orientation is a piece of metadata stored inside image files
@@ -46,9 +48,11 @@
46
48
  * library or WASM module; this utility intentionally avoids extra dependencies.
47
49
  *
48
50
  * Output type & quality
49
- * - Default output is `image/jpeg` with `quality=0.85`, which is typically
50
- * appropriate for avatars. You can switch to `image/png` to preserve
51
- * transparency.
51
+ * - When `type` is omitted the source format is kept if the canvas can encode
52
+ * it: a PNG stays a PNG (preserving transparency) and everything else is
53
+ * encoded as `image/jpeg`. Set `type` explicitly to force a format.
54
+ * - JPEG `quality` is optional; when omitted the browser's native encoding
55
+ * quality is used rather than an imposed value.
52
56
  * - The output filename extension is adjusted to match the chosen MIME type by
53
57
  * default (e.g., `.jpg` or `.png`). You can override naming via the `rename`
54
58
  * option.
@@ -73,9 +77,9 @@
73
77
  * const processed = await resizeImage(file, {
74
78
  * width: 400,
75
79
  * height: 400,
76
- * fit: 'cover', // default; center-crops
77
- * type: 'image/jpeg', // default
78
- * quality: 0.85, // default
80
+ * fit: 'cover', // center-crops; omit to fit without cropping
81
+ * type: 'image/jpeg', // omit to keep the source format
82
+ * quality: 0.85, // omit to use the browser's native quality
79
83
  * });
80
84
  * // Upload `processed` instead of the original file
81
85
  * ```
@@ -120,11 +124,24 @@ export type ResizeOptions = {
120
124
  * keep the source dimensions and only re-encode.
121
125
  */
122
126
  height?: number;
123
- /** Fit strategy; defaults to 'cover'. */
127
+ /**
128
+ * How the image is fitted into the target box when its aspect ratio
129
+ * differs. `cover` scales to fill and center-crops the overflow; `contain`
130
+ * scales to fit the whole image inside the box. Omit to scale the whole
131
+ * image to fit without cropping (no pixels are discarded). Only relevant
132
+ * when both `width` and `height` are set.
133
+ */
124
134
  fit?: 'cover' | 'contain';
125
- /** Output MIME type; 'image/jpeg' by default. */
135
+ /**
136
+ * Output MIME type. Omit to keep the source file's format when the canvas
137
+ * can encode it: a PNG stays a PNG (preserving transparency), otherwise
138
+ * the output is JPEG. Set explicitly to force a format.
139
+ */
126
140
  type?: 'image/jpeg' | 'image/png';
127
- /** JPEG quality (0..1); used only for 'image/jpeg'. Defaults to 0.85. */
141
+ /**
142
+ * JPEG quality (0..1); used only for 'image/jpeg'. Omit to let the browser
143
+ * use its native encoding quality rather than imposing a value.
144
+ */
128
145
  quality?: number;
129
146
  /** Optional renaming function. Defaults to changing extension to match MIME. */
130
147
  rename?: (originalName: string) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@limetech/lime-elements",
3
- "version": "39.42.0",
3
+ "version": "39.42.2",
4
4
  "description": "Lime Elements",
5
5
  "author": "Lime Technologies",
6
6
  "license": "Apache-2.0",
@@ -1 +0,0 @@
1
- async function t(t,e){const{fit:o="cover",type:i="image/jpeg",quality:r=.85,rename:a=t=>n(t,i)}=e,c=await async function(t){var n,e;if("function"==typeof globalThis.createImageBitmap)try{return await globalThis.createImageBitmap(t,{imageOrientation:"from-image"})}catch(t){"production"!==(null===(e=null===(n=globalThis.process)||void 0===n?void 0:n.env)||void 0===e?void 0:e.NODE_ENV)&&"undefined"!=typeof console&&"function"==typeof console.debug&&console.debug("createImageBitmap failed, falling back to HTMLImageElement:",t)}return await async function(t){var n;const e=URL.createObjectURL(t);try{const t=new Image;return t.decoding="sync",t.src=e,await(null===(n=t.decode)||void 0===n?void 0:n.call(t).catch((()=>{}))),t.complete||await new Promise(((n,e)=>{const o=()=>{t.removeEventListener("load",i),t.removeEventListener("error",r)},i=()=>{o(),n()},r=t=>{o(),e(t)};t.addEventListener("load",i),t.addEventListener("error",r)})),t}finally{URL.revokeObjectURL(e)}}(t)}(t),s=c.width,l=c.height,{width:u,height:d}=function(t,n,e,o){const i="number"==typeof e&&e>0,r="number"==typeof o&&o>0;return i&&r?{width:e,height:o}:i?{width:e,height:Math.round(e*(n/t))}:r?{width:Math.round(o*(t/n)),height:o}:{width:t,height:n}}(s,l,e.width,e.height),{sx:h,sy:f,sw:w,sh:y,dx:g,dy:m,dw:p,dh:v}=function(t,n,e,o,i){const r=t/n,a=e/o;if("cover"===i){let i,c;return r>a?(c=n,i=n*a):(i=t,c=t/a),{sx:(t-i)/2,sy:(n-c)/2,sw:i,sh:c,dx:0,dy:0,dw:e,dh:o}}let c,s;r>a?(c=e,s=e/r):(s=o,c=o*r);return{sx:0,sy:0,sw:t,sh:n,dx:(e-c)/2,dy:(o-s)/2,dw:c,dh:s}}(s,l,u,d,o),b=function(t,n){if(function(){try{return"function"==typeof globalThis.OffscreenCanvas}catch(t){return!1}}())return new globalThis.OffscreenCanvas(t,n);const e=document.createElement("canvas");return e.width=t,e.height=n,e}(u,d),x=function(t){const n=t.getContext("2d",{alpha:!0});if(!n)throw new Error("2D canvas context not available");return n}(b);x.clearRect(0,0,u,d),x.drawImage(c,h,f,w,y,g,m,p,v);const T=await function(t,n,e){return"convertToBlob"in t?t.convertToBlob({type:n,quality:e}):new Promise(((o,i)=>{t.toBlob((t=>{t?o(t):i(new Error("Failed to create blob from canvas"))}),n,e)}))}(b,i,r),E=a(t.name);return new File([T],E,{type:i})}function n(t,n){const e="image/png"===n?"png":"jpg",o=t.lastIndexOf(".");return`${o>0?t.slice(0,o):t}.${e}`}export{t as r}
@@ -1 +0,0 @@
1
- import{r as t,c as e,h as i,H as r}from"./p-BGxJfR2f.js";import{i as o}from"./p-C4caLnTg.js";import{g as s}from"./p-CgNJbSP4.js";import{t as a}from"./p-Cb9R_zmF.js";import{c as n}from"./p-JbKhhoXs.js";import{r as l}from"./p-65ma7B85.js";import{I as h}from"./p-Dpg0OkbJ.js";import"./p-BCq5M9TE.js";import"./p-Bu_YRgCL.js";const c=class{constructor(r){t(this,r),this.change=e(this,"change"),this.filesRejected=e(this,"filesRejected"),this.language="en",this.icon="user",this.disabled=!1,this.readonly=!1,this.required=!1,this.invalid=!1,this.loading=!1,this.imageFit="cover",this.accept="image/jpeg,image/png,image/heic,.jpg,.jpeg,.png,.heic",this.imageError=!1,this.isErrorMessagePopoverOpen=!1,this.removeButtonId=n(),this.browseButtonId=n(),this.renderHelperText=()=>{if(this.helperText)return i("limel-tooltip",{elementId:this.browseButtonId,label:this.helperText})},this.handleNewFiles=async t=>{var e,i;if(t.stopPropagation(),this.disabled)return;const r=null===(e=t.detail)||void 0===e?void 0:e[0];if(!r)return;if(!o(r,this.accept))return void this.filesRejected.emit([r]);this.revokeObjectUrl(),this.imageError=!1;let s=r;if(this.resize&&r.fileContent instanceof File)try{const t=await l(r.fileContent,Object.assign(Object.assign({},this.resize),{fit:null!==(i=this.resize.fit)&&void 0!==i?i:this.imageFit}));s=Object.assign(Object.assign({},r),{filename:t.name,size:t.size,contentType:t.type,fileContent:t})}catch(t){s=r}!s.href&&s.fileContent instanceof File&&(this.objectUrl=URL.createObjectURL(s.fileContent)),this.change.emit(s)},this.handleRejectedFiles=t=>{t.stopPropagation(),this.filesRejected.emit(t.detail)},this.handleClear=t=>{t.stopPropagation(),this.revokeObjectUrl(),this.imageError=!1,this.change.emit(void 0)},this.onImageError=()=>{this.imageError=!0},this.openPopover=t=>{t.stopPropagation(),this.isErrorMessagePopoverOpen=!0},this.onPopoverClose=t=>{t.stopPropagation(),this.isErrorMessagePopoverOpen=!1},this.getTranslation=t=>a.get(t,this.language)}disconnectedCallback(){this.revokeObjectUrl()}handleValueChange(){this.revokeObjectUrl(),this.imageError=!1;const t=this.value;t&&"string"!=typeof t&&!t.href&&t.fileContent instanceof File&&(this.objectUrl=URL.createObjectURL(t.fileContent))}render(){const t={"has-image-error":this.imageError};return this.readonly?i(r,{class:t},this.renderAvatar()):i(r,{class:t},i("limel-file-dropzone",{disabled:this.disabled,accept:this.accept,onFilesSelected:this.handleNewFiles,onFilesRejected:this.handleRejectedFiles},i("limel-file-input",{accept:this.accept,disabled:this.disabled,"aria-required":this.required?"true":void 0,"aria-invalid":this.invalid?"true":void 0},this.renderBrowseButton())),this.renderClearButton(),this.renderSpinner(),this.renderErrorMessage(),this.renderHelperText())}get hasValue(){return"string"==typeof this.value?!!this.value:!(!this.value||!this.value.href&&!this.value.fileContent)||!!this.objectUrl}renderBrowseButton(){return i("button",{id:this.browseButtonId,type:"button",class:"avatar",disabled:this.disabled,"aria-label":this.label,"aria-busy":this.loading?"true":"false","aria-live":"polite"},this.renderAvatar())}renderAvatar(){const t=this.getImageSrc();return t?i(h,{image:{src:t,alt:"",referrerpolicy:"no-referrer"},style:{"--limel-profile-picture-object-fit":this.imageFit},onError:this.onImageError}):this.renderIcon()}renderIcon(){var t,e;const r=s(this.icon);return i("limel-icon",{name:r,style:{color:`${null===(t=this.icon)||void 0===t?void 0:t.color}`,"background-color":`${null===(e=this.icon)||void 0===e?void 0:e.backgroundColor}`}})}renderClearButton(){if(this.hasValue&&!this.disabled)return[i("button",{class:"remove",type:"button",id:this.removeButtonId,onClick:this.handleClear}),i("limel-tooltip",{label:this.getTranslation("profile-picture.remove"),elementId:this.removeButtonId})]}renderSpinner(){if(this.loading)return i("limel-spinner",null)}getUnsupportedPreviewContext(){const t=this.value;return{hasNoSrc:!this.getImageSrc(),hasLocalFile:!(!(t&&"string"!=typeof t&&t.fileContent instanceof File)||t.href),isResizeConfigured:!!this.resize}}shouldShowErrorMessage(){const{hasNoSrc:t,hasLocalFile:e,isResizeConfigured:i}=this.getUnsupportedPreviewContext();return(t||this.imageError)&&e&&i}renderErrorMessage(){if(this.shouldShowErrorMessage())return i("limel-popover",{open:this.isErrorMessagePopoverOpen,onClick:this.openPopover,onClose:this.onPopoverClose},i("limel-icon-button",{slot:"trigger",elevated:!0,icon:{name:"error",color:"rgb(var(--color-orange-dark))"},"aria-live":"polite",label:this.getTranslation("profile-picture.unsupported-preview.title")}),i("limel-callout",{type:"warning",style:{maxWidth:"20rem",borderRadius:"0.75rem"},heading:this.getTranslation("profile-picture.unsupported-preview.title")},this.getTranslation("profile-picture.unsupported-preview.description")))}getImageSrc(){return this.value?"string"==typeof this.value?this.value:this.value.href?this.value.href:this.value.fileContent instanceof File?this.objectUrl:void 0:this.objectUrl}revokeObjectUrl(){this.objectUrl&&(URL.revokeObjectURL(this.objectUrl),this.objectUrl=void 0)}static get watchers(){return{value:[{handleValueChange:0}]}}};c.style="@charset \"UTF-8\";:host(limel-profile-picture){position:relative;display:inline-flex;min-width:1.5rem;min-height:1.5rem;border-radius:var(--profile-picture-border-radius, 100vw);background-color:rgb(var(--contrast-400))}*{box-sizing:border-box}limel-file-dropzone,limel-file-input,button.avatar{display:flex;align-items:center;justify-content:center;width:100%;height:100%}button{appearance:none;background:none;border:none;padding:0;margin:0;font:inherit;color:inherit;text-align:inherit;display:block}button:focus{outline:none}button:focus-visible{outline:none;box-shadow:var(--shadow-depth-8-focused)}button.avatar{overflow:hidden;border-radius:var(--profile-picture-border-radius, 100vw)}:host(:not([disabled]):not([disabled=true])) button.avatar{transition:color var(--limel-clickable-transition-speed, 0.4s) ease, background-color var(--limel-clickable-transition-speed, 0.4s) ease, box-shadow var(--limel-clickable-transform-speed, 0.4s) ease, transform var(--limel-clickable-transform-speed, 0.4s) var(--limel-clickable-transform-timing-function, ease);cursor:pointer;color:var(--limel-theme-on-surface-color);background-color:transparent}:host(:not([disabled]):not([disabled=true])) button.avatar:hover,:host(:not([disabled]):not([disabled=true])) button.avatar:focus,:host(:not([disabled]):not([disabled=true])) button.avatar:focus-visible{will-change:color, background-color, box-shadow, transform}:host(:not([disabled]):not([disabled=true])) button.avatar:hover,:host(:not([disabled]):not([disabled=true])) button.avatar:focus-visible{transform:translate3d(0, 0.01rem, 0);color:var(--limel-theme-on-surface-color);background-color:var(--lime-elevated-surface-background-color)}:host(:not([disabled]):not([disabled=true])) button.avatar:hover{box-shadow:var(--button-shadow-hovered)}:host(:not([disabled]):not([disabled=true])) button.avatar:active{--limel-clickable-transform-timing-function:cubic-bezier( 0.83, -0.15, 0.49, 1.16 );transform:translate3d(0, 0.05rem, 0);box-shadow:var(--button-shadow-pressed)}:host(:not([disabled]):not([disabled=true])) button.avatar:hover,:host(:not([disabled]):not([disabled=true])) button.avatar:active{--limel-clickable-transition-speed:0.2s;--limel-clickable-transform-speed:0.16s}:host([invalid]:not([invalid=false])) button.avatar{box-shadow:var(--shadow-error-state)}button.remove{transition:color var(--limel-clickable-transition-speed, 0.4s) ease, background-color var(--limel-clickable-transition-speed, 0.4s) ease, box-shadow var(--limel-clickable-transform-speed, 0.4s) ease, transform var(--limel-clickable-transform-speed, 0.4s) var(--limel-clickable-transform-timing-function, ease);cursor:pointer;color:var(--limel-theme-on-surface-color);background-color:rgb(var(--contrast-900))}button.remove:hover,button.remove:focus,button.remove:focus-visible{will-change:color, background-color, box-shadow, transform}button.remove:hover,button.remove:focus-visible{transform:translate3d(0, 0.01rem, 0);color:rgb(var(--color-white));background-color:rgb(var(--color-red-default))}button.remove:hover{box-shadow:var(--button-shadow-hovered)}button.remove:active{--limel-clickable-transform-timing-function:cubic-bezier( 0.83, -0.15, 0.49, 1.16 );transform:translate3d(0, 0.05rem, 0);box-shadow:var(--button-shadow-pressed)}button.remove:hover,button.remove:active{--limel-clickable-transition-speed:0.2s;--limel-clickable-transform-speed:0.16s}button.remove{cursor:pointer;height:1.25rem;width:1.25rem;border-radius:50%;background-repeat:no-repeat;background-position:center;background-size:0.75rem;background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2032%2032'%3E%3Cdefs/%3E%3Cpath%20fill='rgb(255,255,255)'%20d='M7.219%205.781L5.78%207.22%2014.563%2016%205.78%2024.781%207.22%2026.22%2016%2017.437l8.781%208.782%201.438-1.438L17.437%2016l8.782-8.781L24.78%205.78%2016%2014.563z'/%3E%3C/svg%3E\");position:absolute;top:0;left:0;opacity:0}:host(:hover) button.remove,:host(:focus) button.remove,:host(:focus-visible) button.remove,:host(:focus-within) button.remove,:host(:active) button.remove{animation:show 0.4s ease-in-out forwards}@keyframes show{0%{transform:scale(0.9);opacity:0}100%{transform:scale(1);opacity:1}}button.avatar,img,limel-icon{border-radius:var(--profile-picture-border-radius, 100vw)}limel-icon{width:calc(100% - 1rem);min-width:1rem;max-width:4rem;color:var(--limel-theme-text-secondary-on-background-color);margin:auto}img{object-fit:var(--limel-profile-picture-object-fit);width:100%;height:100%}:host(.has-image-error) img{border:1px dashed rgb(var(--contrast-600));background:url(\"data:image/svg+xml;charset=utf-8, <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' style='fill-rule:evenodd;'><path fill='rgba(186,186,192,0.16)' d='M0 0h4v4H0zM4 4h4v4H4z'/></svg>\");background-size:0.5rem}limel-spinner{position:absolute;inset:0;margin:auto}limel-popover{position:absolute;inset:auto 0 0 auto;display:block;width:2.25rem;height:2.25rem}";export{c as limel_profile_picture}