@taprootio/espalier 4.9.1 → 4.10.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.
- package/CHANGELOG.md +14 -0
- package/custom-elements.json +6666 -6468
- package/dist/image/esp-image.d.ts +13 -0
- package/dist/image/esp-image.js +9 -9
- package/dist/image-upload/esp-image-upload.d.ts +8 -0
- package/dist/image-upload/esp-image-upload.js +18 -18
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/shared/justified-layout.d.ts +15 -1
- package/dist/shared/justified-layout.js +1 -1
- package/package.json +1 -1
|
@@ -75,6 +75,12 @@ export declare function parseImageRatio(value: string): string | null;
|
|
|
75
75
|
* </esp-image>
|
|
76
76
|
* ```
|
|
77
77
|
*
|
|
78
|
+
* For a long projected lazy-image list, `defer-offscreen` keeps the served
|
|
79
|
+
* `sizes` hint until an image approaches the viewport. This avoids replacing a
|
|
80
|
+
* small fallback selection with a larger candidate before the image can be
|
|
81
|
+
* seen. Eager projected images and every non-projected source keep the normal
|
|
82
|
+
* immediate measured-size behavior.
|
|
83
|
+
*
|
|
78
84
|
* Banner mode gives all three source modes the same focal position, scrim,
|
|
79
85
|
* texture, and semantic overlay stack. `ratio` applies at wide widths and
|
|
80
86
|
* `compact-ratio` below the component-relative compact threshold.
|
|
@@ -284,6 +290,13 @@ export declare class EspalierImage extends EspalierElementBase {
|
|
|
284
290
|
* retain the consumer's own loading attributes.
|
|
285
291
|
*/
|
|
286
292
|
loading: "eager" | "lazy";
|
|
293
|
+
/**
|
|
294
|
+
* For lazy projected images, defer measured `sizes` upgrades until the image
|
|
295
|
+
* approaches the viewport. A 200px prefetch margin keeps the full-size
|
|
296
|
+
* candidate ready before it is visible. Eager projections and internally
|
|
297
|
+
* rendered images keep their normal immediate measurements.
|
|
298
|
+
*/
|
|
299
|
+
deferOffscreen: boolean;
|
|
287
300
|
/** Enable borderless banner defaults and the decorative/content layer stack. */
|
|
288
301
|
banner: boolean;
|
|
289
302
|
/**
|
package/dist/image/esp-image.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
var n=function(
|
|
1
|
+
var n=function(d,e,t,r){var i=arguments.length,s=i<3?e:r===null?r=Object.getOwnPropertyDescriptor(e,t):r,o;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(d,e,t,r);else for(var l=d.length-1;l>=0;l--)(o=d[l])&&(s=(i<3?o(s):i>3?o(e,t,s):o(e,t))||s);return i>3&&s&&Object.defineProperty(e,t,s),s},p;import{css as I,html as m,nothing as C}from"lit";import{customElement as $,property as c,state as g}from"lit/decorators.js";import{EspalierElementBase as v}from"../shared/esp-element-base.js";import{slotHasContent as y}from"../shared/slot-content.js";import{renderVisualOverlay as T,visualOverlayStyles as A}from"../shared/visual-overlay.js";import{focusConverter as N,normalizeFocus as R}from"./image-focus.js";import{ensureImageTextureFilters as W,imageTextureFilterId as E}from"./image-texture-filters.js";import{getImageTexture as b,isBuiltInImageTexture as x,subscribeToImageTextureRegistry as M}from"../shared/image-texture-registry.js";import{validImageDimensions as _}from"./image-dimensions.js";import"./esp-image-option.js";const k=new Set(["auto","none","flat","top","bottom","left","right","radial"]),S=new Set(["soft","medium","strong"]),w=new Set(["fine","medium","coarse"]),j=new Set(["auto","light","dark"]),O=new Set(["bottom-start","bottom","bottom-end","center","top-start","top","top-end"]);function h(d,e){return{fromAttribute(t){return t&&d.has(t)?t:e},toAttribute(t){return d.has(t)?t:e}}}function z(d){const e=d.trim();if(!e)return null;const t=e.split("/").map(i=>i.trim());if(t.length>2||t.some(i=>i.length===0))return null;const r=t.map(Number);return r.some(i=>!Number.isFinite(i)||i<=0)?null:r.length===1?String(r[0]):`${r[0]} / ${r[1]}`}let a=p=class extends v{constructor(){super(...arguments),this.originalHeight=0,this.originalWidth=0,this.imageUrl="",this.localImage="",this.caption="",this.sizes="100vw",this.loading="eager",this.deferOffscreen=!1,this.banner=!1,this.bannerScheme="auto",this.scrim="auto",this.scrimStrength="medium",this.texture="none",this.textureScale="medium",this.contentPosition="bottom-start",this.focusPoint={x:.5,y:.5},this.ratio="",this.compactRatio="",this.renderedWidth=0,this.measuredWidth=0,this.compact=!1,this.overlayHasContent=!1,this.resizeObserver=null,this.offscreenObserver=null,this.offscreenAdmitted=!1,this.deferredProjectedImage=null,this.unsubscribeTextures=null,this.handleSlotChange=e=>{if(e.target instanceof HTMLSlotElement){if(e.target.name==="overlay"){const t=y(e.target);t!==this.overlayHasContent&&(this.overlayHasContent=t);return}this.requestUpdate()}}}get isPortrait(){const e=_(this.originalWidth,this.originalHeight);return e!==null&&e.height>e.width}findProjected(){for(const e of this.children)if(e.tagName==="PICTURE"||e.tagName==="IMG")return e;return null}findProjectedImage(e=this.findProjected()){return e?e.tagName==="IMG"?e:e.querySelector("img"):null}requiresOffscreenDeferral(e=this.findProjectedImage()){return this.deferOffscreen&&e?.getAttribute("loading")?.toLowerCase()==="lazy"}shouldDeferProjectedSizes(){return this.requiresOffscreenDeferral()&&!this.offscreenAdmitted}applyMeasuredWidth(){this.measuredWidth>0&&this.measuredWidth!==this.renderedWidth&&(this.renderedWidth=this.measuredWidth)}syncOffscreenDeferral(){const e=this.findProjectedImage();if(e!==this.deferredProjectedImage&&(this.offscreenAdmitted=!1,this.offscreenObserver?.disconnect(),this.offscreenObserver=null,this.deferredProjectedImage=e),!this.requiresOffscreenDeferral(e)){this.offscreenObserver?.disconnect(),this.offscreenObserver=null,this.offscreenAdmitted=!1,this.deferredProjectedImage=null,this.applyMeasuredWidth();return}if(!this.offscreenAdmitted){if(typeof IntersectionObserver>"u"){this.offscreenAdmitted=!0,this.applyMeasuredWidth();return}if(!this.offscreenObserver){const t=e,r=new IntersectionObserver(i=>{if(this.offscreenObserver===r){if(this.findProjectedImage()!==t){this.syncOffscreenDeferral();return}i.some(s=>s.isIntersecting)&&(this.offscreenAdmitted=!0,this.offscreenObserver?.disconnect(),this.offscreenObserver=null,this.applyMeasuredWidth(),this.requestUpdate())}},{rootMargin:"200px"});this.offscreenObserver=r}this.offscreenObserver.observe(this)}}connectedCallback(){super.connectedCallback(),p.ensureProjectionStyles(this.getRootNode()),this.unsubscribeTextures??=M(()=>this.requestUpdate()),this.resizeObserver??=new ResizeObserver(e=>{const t=e[0]?.contentBoxSize?.[0],r=Math.round(t?t.inlineSize:e[0]?.contentRect.width??0);r<=0||(this.measuredWidth=r,this.syncOffscreenDeferral(),this.applyMeasuredWidth())}),this.resizeObserver.observe(this),this.syncOffscreenDeferral()}disconnectedCallback(){super.disconnectedCallback(),this.unsubscribeTextures?.(),this.unsubscribeTextures=null,this.resizeObserver?.disconnect(),this.resizeObserver=null,this.offscreenObserver?.disconnect(),this.offscreenObserver=null,this.offscreenAdmitted=!1,this.deferredProjectedImage=null}effectiveSizes(){return this.renderedWidth>0?`${this.renderedWidth}px`:this.sizes}buildSources(){const e=new Map;for(const t of this.querySelectorAll("esp-image-option")){const r=t.getAttribute("url"),i=Number(t.getAttribute("width"));if(!r||!Number.isFinite(i)||i<=0)continue;const s=t.getAttribute("type")??"",o=e.get(s)??[];o.push({url:r,width:i}),e.set(s,o)}return Array.from(e,([t,r])=>({type:t,srcset:r.sort((i,s)=>i.width-s.width).map(i=>`${i.url} ${i.width}w`).join(", ")})).filter(t=>t.srcset.length>0)}resolvedBannerScheme(){return this.bannerScheme!=="auto"?this.bannerScheme:this.scheme==="dark"?"dark":"light"}resolvedTexture(){return x(this.texture)?this.texture:b(this.texture)?this.texture:"none"}resolvedScrim(){return this.scrim!=="auto"?this.scrim:this.overlayHasContent?this.contentPosition.startsWith("top")?"top":this.contentPosition.startsWith("bottom")?"bottom":"radial":"none"}resolvedAspectRatio(){const e=_(this.originalWidth,this.originalHeight);if(!this.banner)return e?`${e.width} / ${e.height}`:null;const t=z(this.ratio);return(this.compact?z(this.compactRatio):null)??t??(e?`${e.width} / ${e.height}`:null)}normalizeEnums(e){e.has("scrim")&&!k.has(this.scrim)&&(this.scrim="auto"),e.has("bannerScheme")&&!j.has(this.bannerScheme)&&(this.bannerScheme="auto"),e.has("scrimStrength")&&!S.has(this.scrimStrength)&&(this.scrimStrength="medium"),e.has("textureScale")&&!w.has(this.textureScale)&&(this.textureScale="medium"),e.has("contentPosition")&&!O.has(this.contentPosition)&&(this.contentPosition="bottom-start")}willUpdate(e){super.willUpdate(e),this.normalizeEnums(e);const t=R(this.focusPoint),r=Number((t.x*100).toFixed(4)),i=Number((t.y*100).toFixed(4));this.style.setProperty("--_esp-image-object-position",`${r}% ${i}%`);const s=this.resolvedAspectRatio();s?this.style.setProperty("--_esp-image-aspect-ratio",s):this.style.removeProperty("--_esp-image-aspect-ratio");const o=this.resolvedTexture();if(["paper","grain","grunge"].includes(o)){const u=o==="grunge"&&this.resolvedBannerScheme()==="light"?"grunge-light":o;this.style.setProperty("--_esp-image-texture-filter",`url(#${E(u,this.textureScale)})`)}else this.style.removeProperty("--_esp-image-texture-filter");const l=x(o)?void 0:b(o),P=[["--_esp-image-registered-image",l?.image],["--_esp-image-registered-size",l?.size],["--_esp-image-registered-repeat",l?.repeat],["--_esp-image-registered-position",l?.position],["--_esp-image-registered-opacity",l?.opacity?.toString()],["--_esp-image-registered-blend-mode",l?.blendMode]];for(const[u,f]of P)f===void 0?this.style.removeProperty(u):this.style.setProperty(u,f)}firstUpdated(e){super.firstUpdated(e);const t=this.shadowRoot?.querySelector('slot[name="overlay"]');t&&(this.overlayHasContent=y(t))}updated(e){if(super.updated(e),this.syncOffscreenDeferral(),["paper","grain","grunge"].includes(this.resolvedTexture())&&this.renderRoot&&W(this.renderRoot),this.renderedWidth>0){const o=this.shadowRoot?.querySelector(".compact-sentinel")?.getBoundingClientRect().width??0,l=o>0&&this.renderedWidth<o;l!==this.compact&&(this.compact=l)}if(this.renderedWidth<=0||this.shouldDeferProjectedSizes())return;const t=this.findProjected();if(!t)return;const r=this.effectiveSizes();if(t.tagName==="PICTURE")for(const s of t.querySelectorAll("source"))s.setAttribute("sizes",r);const i=this.findProjectedImage(t);i?.hasAttribute("srcset")&&i.setAttribute("sizes",r)}renderMedia(){if(this.localImage)return m`<img
|
|
2
2
|
src=${this.localImage}
|
|
3
3
|
alt=${this.caption}
|
|
4
4
|
decoding="async"
|
|
5
5
|
loading=${this.loading}
|
|
6
|
-
/>`;const e=
|
|
6
|
+
/>`;const e=m`<slot @slotchange=${this.handleSlotChange}></slot>`;if(this.findProjected())return e;const t=this.buildSources();return m`
|
|
7
7
|
<picture>
|
|
8
|
-
${t.map(r=>
|
|
8
|
+
${t.map(r=>m`
|
|
9
9
|
<source
|
|
10
10
|
srcset=${r.srcset}
|
|
11
11
|
sizes=${this.effectiveSizes()}
|
|
12
|
-
type=${r.type||
|
|
12
|
+
type=${r.type||C}
|
|
13
13
|
/>
|
|
14
14
|
`)}
|
|
15
15
|
<img src=${this.imageUrl} alt=${this.caption} decoding="async" loading=${this.loading} />
|
|
16
16
|
</picture>
|
|
17
17
|
${e}
|
|
18
|
-
`}render(){return
|
|
18
|
+
`}render(){return m`
|
|
19
19
|
<div
|
|
20
20
|
part="frame"
|
|
21
21
|
class="frame"
|
|
@@ -27,13 +27,13 @@ var n=function(p,e,t,r){var i=arguments.length,o=i<3?e:r===null?r=Object.getOwnP
|
|
|
27
27
|
data-content-position=${this.contentPosition}
|
|
28
28
|
>
|
|
29
29
|
<div part="image" class="image">${this.renderMedia()}</div>
|
|
30
|
-
${
|
|
30
|
+
${T({className:"banner-layers",imagePart:"texture",scrimPart:"scrim",texturePart:"texture"})}
|
|
31
31
|
<div part="overlay" class="overlay" ?hidden=${!this.banner||!this.overlayHasContent}>
|
|
32
32
|
<slot name="overlay" @slotchange=${this.handleSlotChange}></slot>
|
|
33
33
|
</div>
|
|
34
34
|
<span class="compact-sentinel" aria-hidden="true"></span>
|
|
35
35
|
</div>
|
|
36
|
-
`}static ensureProjectionStyles(e){const t=e.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&"host"in e?e:e.nodeType===Node.DOCUMENT_NODE?e.head:e.ownerDocument?.head??document.head,r=Array.from(t.querySelectorAll("style[data-esp-image-projection-styles]")),i=r.find(
|
|
36
|
+
`}static ensureProjectionStyles(e){const t=e.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&"host"in e?e:e.nodeType===Node.DOCUMENT_NODE?e.head:e.ownerDocument?.head??document.head,r=Array.from(t.querySelectorAll("style[data-esp-image-projection-styles]")),i=r.find(o=>o.textContent===p.projectionStyles);if(i){for(const o of r)o!==i&&o.remove();return}for(const o of r)o.remove();const s=t.ownerDocument.createElement("style");s.dataset.espImageProjectionStyles="",s.textContent=p.projectionStyles,t.append(s)}};a.projectionStyles=`
|
|
37
37
|
esp-image > picture,
|
|
38
38
|
esp-image > img {
|
|
39
39
|
display: block;
|
|
@@ -49,7 +49,7 @@ var n=function(p,e,t,r){var i=arguments.length,o=i<3?e:r===null?r=Object.getOwnP
|
|
|
49
49
|
object-fit: var(--_esp-image-object-fit, cover);
|
|
50
50
|
object-position: var(--esp-image-object-position, var(--_esp-image-object-position, center));
|
|
51
51
|
}
|
|
52
|
-
`,a.styles=[...
|
|
52
|
+
`,a.styles=[...v.styles,I`
|
|
53
53
|
:host {
|
|
54
54
|
display: block;
|
|
55
55
|
aspect-ratio: var(--_esp-image-aspect-ratio, auto);
|
|
@@ -439,4 +439,4 @@ var n=function(p,e,t,r){var i=arguments.length,o=i<3?e:r===null?r=Object.getOwnP
|
|
|
439
439
|
transition: none !important;
|
|
440
440
|
}
|
|
441
441
|
}
|
|
442
|
-
`,
|
|
442
|
+
`,A],n([c({attribute:"original-height",type:Number})],a.prototype,"originalHeight",void 0),n([c({attribute:"original-width",type:Number})],a.prototype,"originalWidth",void 0),n([c({attribute:"low-res",type:String})],a.prototype,"imageUrl",void 0),n([c({attribute:"local-image",type:String})],a.prototype,"localImage",void 0),n([c({type:String})],a.prototype,"caption",void 0),n([c({attribute:"sizes",type:String})],a.prototype,"sizes",void 0),n([c({attribute:"loading",type:String})],a.prototype,"loading",void 0),n([c({attribute:"defer-offscreen",type:Boolean})],a.prototype,"deferOffscreen",void 0),n([c({type:Boolean,reflect:!0})],a.prototype,"banner",void 0),n([c({attribute:"banner-scheme",converter:h(j,"auto"),reflect:!0})],a.prototype,"bannerScheme",void 0),n([c({converter:h(k,"auto"),reflect:!0})],a.prototype,"scrim",void 0),n([c({attribute:"scrim-strength",converter:h(S,"medium"),reflect:!0})],a.prototype,"scrimStrength",void 0),n([c({type:String,reflect:!0})],a.prototype,"texture",void 0),n([c({attribute:"texture-scale",converter:h(w,"medium"),reflect:!0})],a.prototype,"textureScale",void 0),n([c({attribute:"content-position",converter:h(O,"bottom-start"),reflect:!0})],a.prototype,"contentPosition",void 0),n([c({attribute:"focus",converter:N,reflect:!0})],a.prototype,"focusPoint",void 0),n([c({type:String})],a.prototype,"ratio",void 0),n([c({attribute:"compact-ratio",type:String})],a.prototype,"compactRatio",void 0),n([g()],a.prototype,"renderedWidth",void 0),n([g()],a.prototype,"compact",void 0),n([g()],a.prototype,"overlayHasContent",void 0),a=p=n([$("esp-image")],a);export{a as EspalierImage,z as parseImageRatio};
|
|
@@ -157,6 +157,14 @@ export declare class EspalierImageUpload extends EspalierElementBase {
|
|
|
157
157
|
* are skipped and reported via the `esp-image-upload-files-rejected` event.
|
|
158
158
|
*/
|
|
159
159
|
accept: string;
|
|
160
|
+
/**
|
|
161
|
+
* Maximum number of image previews in each justified row. Positive integers
|
|
162
|
+
* create a hard row boundary; omitted, non-finite, non-integer, and
|
|
163
|
+
* nonpositive values leave rows unlimited.
|
|
164
|
+
*
|
|
165
|
+
* @type {number}
|
|
166
|
+
*/
|
|
167
|
+
maxImagesPerRow?: number;
|
|
160
168
|
connectedCallback(): void;
|
|
161
169
|
disconnectedCallback(): void;
|
|
162
170
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var g=function(v,e,t,
|
|
1
|
+
var g=function(v,e,t,i){var n=arguments.length,s=n<3?e:i===null?i=Object.getOwnPropertyDescriptor(e,t):i,l;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(v,e,t,i);else for(var r=v.length-1;r>=0;r--)(l=v[r])&&(s=(n<3?l(s):n>3?l(e,t,s):l(e,t))||s);return n>3&&s&&Object.defineProperty(e,t,s),s},_;import{css as D,html as m}from"lit";import{customElement as A,property as S,state as w}from"lit/decorators.js";import{createRef as b,ref as x}from"lit/directives/ref.js";import"./esp-image-preview.js";import{classMap as y}from"lit/directives/class-map.js";import{getImageDetails as R,releasePreviewUrl as I}from"./image-helpers.js";const k=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
|
2
2
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
3
3
|
<path d="M11.911 3.634a2 2 0 0 1 1.089 1.78l.001 2.586h6.999a2 2 0 0 1 2 2v4l-.005 .15a2 2 0 0 1 -1.995 1.85l-6.999 -.001l-.001 2.587a2 2 0 0 1 -3.414 1.414l-6.586 -6.586a2 2 0 0 1 0 -2.828l6.586 -6.586a2 2 0 0 1 2.18 -.434l.145 .068z" />
|
|
4
|
-
</svg>`,
|
|
4
|
+
</svg>`,C=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
|
5
5
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
6
6
|
<path d="M12.089 3.634a2 2 0 0 0 -1.089 1.78l-.001 2.586h-6.999a2 2 0 0 0 -2 2v4l.005 .15a2 2 0 0 0 1.995 1.85l6.999 -.001l.001 2.587a2 2 0 0 0 3.414 1.414l6.586 -6.586a2 2 0 0 0 0 -2.828l-6.586 -6.586a2 2 0 0 0 -2.18 -.434l-.145 .068z" />
|
|
7
|
-
</svg>`;import{EspalierElementBase as
|
|
7
|
+
</svg>`;import{EspalierElementBase as P}from"../shared/esp-element-base.js";import{calculatePhotoLayout as M}from"../shared/justified-layout.js";import{ESP_EVENTS as f}from"../shared/events.js";const E=220,U=4,L=8e3;let p=_=class extends P{constructor(){super(...arguments),this.uploadInput=b(),this.previewsDiv=b(),this.dropAreaDiv=b(),this.draggingOver=!1,this.uploadedImages=[],this.accept="image/jpeg, image/png, image/webp",this._rejectionNotice="",this._uploadState=new WeakMap,this._selectionGeneration=0,this._chromeWidth=null,this._resizeObserver=new ResizeObserver(()=>{this._chromeWidth=null,this.requestUpdate()}),this._dragPointerId=null,this._dragSourceIndex=null,this._dragOverIndex=null,this._dragStartX=0,this._dragStartY=0,this._dragActive=!1,this._ghostEl=null,this._ghostHalfW=0,this._ghostHalfH=0,this._arrowEl=null,this._cachedPreviews=null,this._lastDropHit=null,this._savedBodyUserSelect="",this._handleDragPointerDown=e=>{if(e.button!==0||this._dragPointerId!==null||e.composedPath().some(n=>n instanceof HTMLElement&&(n.tagName==="BUTTON"||n.tagName==="ESP-BUTTON")))return;const i=this._getPreviewIndex(e);i!==null&&(this._dragPointerId=e.pointerId,this._dragSourceIndex=i,this._dragStartX=e.clientX,this._dragStartY=e.clientY,this._dragActive=!1,document.addEventListener("pointermove",this._onDocPointerMove),document.addEventListener("pointerup",this._onDocPointerUp),document.addEventListener("pointercancel",this._onDocPointerUp))},this._onDocPointerMove=e=>{if(this._dragSourceIndex===null||e.pointerId!==this._dragPointerId)return;const t=e.clientX-this._dragStartX,i=e.clientY-this._dragStartY;if(!this._dragActive){if(Math.sqrt(t*t+i*i)<_._DRAG_THRESHOLD)return;this._dragActive=!0,this._createGhost(e.clientX,e.clientY);const r=this.shadowRoot?.querySelectorAll("esp-image-preview");r&&(this._cachedPreviews=Array.from(r).map(o=>({el:o,rect:o.getBoundingClientRect()})),this._dragSourceIndex!==null&&this._dragSourceIndex<this._cachedPreviews.length&&(this._cachedPreviews[this._dragSourceIndex].el.style.opacity="0.3")),this._savedBodyUserSelect=document.body.style.userSelect,document.body.style.userSelect="none",this.previewsDiv.value&&(this.previewsDiv.value.style.touchAction="none")}this._ghostEl&&(this._ghostEl.style.transform=`translate(${e.clientX-this._ghostHalfW}px, ${e.clientY-this._ghostHalfH}px)`);const n=this._cachedPreviews;if(!n||n.length===0)return;let s=null,l=!1;for(let r=0;r<n.length;r++){const o=n[r].rect;if(e.clientX>=o.left&&e.clientX<=o.right&&e.clientY>=o.top&&e.clientY<=o.bottom){s=r,l=e.clientX>o.left+o.width/2;break}}if(s===null){let r=1/0;for(let o=0;o<n.length;o++){const a=n[o].rect,d=e.clientX-(a.left+a.width/2),h=e.clientY-(a.top+a.height/2),c=d*d+h*h;c<r&&(r=c,s=o)}if(s!==null){const o=n[s].rect;l=e.clientX>o.left+o.width/2}}s!==null&&(this._dragOverIndex=l?s+1:s,!(this._lastDropHit&&this._lastDropHit.index===s&&this._lastDropHit.after===l)&&(this._lastDropHit={index:s,after:l},this._updateDropTargets(n.map(r=>r.el),s,l)))},this._onDocPointerUp=e=>{if(e.pointerId===this._dragPointerId){if(this._dragActive&&this._dragSourceIndex!==null&&this._dragOverIndex!==null&&this._dragSourceIndex!==this._dragOverIndex&&this._dragSourceIndex+1!==this._dragOverIndex){const t=[...this.uploadedImages],[i]=t.splice(this._dragSourceIndex,1),n=this._dragOverIndex>this._dragSourceIndex?this._dragOverIndex-1:this._dragOverIndex;t.splice(n,0,i),this.uploadedImages=t,this.dispatchEvent(new CustomEvent(f.IMAGE_UPLOAD_IMAGES_REORDERED,{detail:{images:this.uploadedImages},bubbles:!0,composed:!0}))}this._clearDragState()}},this._arrowColor=null,this.filesSelected=async e=>{const t=[],i=[];for(const d of e)(this._isAccepted(d)?t:i).push(d);if(!t.length){i.length&&this._reportRejectedFiles({unsupported:i,unreadable:[]});return}const n=this._selectionGeneration,s=Math.round(E*Math.min(globalThis.devicePixelRatio||1,2)),l=new Array(t.length).fill(null),r=[];let o=0;const a=async()=>{for(;o<t.length;){const d=o++,h=t[d];try{const c=await R(h,{thumbnailHeight:s});if(n!==this._selectionGeneration){I(c);continue}this._addSelectedImage(l,d,c)}catch{r.push(h)}}};await Promise.all(Array.from({length:Math.min(U,t.length)},()=>a())),(i.length||r.length)&&n===this._selectionGeneration&&this._reportRejectedFiles({unsupported:i,unreadable:r})},this._makeCallbacks=e=>({onProgress:t=>{const i=this._uploadState.get(e);i&&(i.progress=t,i.failed=!1,this.requestUpdate())},onComplete:t=>{if(!this._uploadState.get(e))return;e.uploadedId=t,this._uploadState.delete(e),!this.uploadedImages.find(s=>!s.uploadedId)?this.uploadedImages=[...this.uploadedImages]:this.requestUpdate()},onFailed:()=>{const t=this._uploadState.get(e);t&&(t.progress=void 0,t.failed=!0,this.requestUpdate())}}),this._fullPreviewUrls=new Map,this.setExistingImages=e=>{this._selectionGeneration++,this._releaseSelectedImages(),this.uploadedImages=e.filter(t=>t.url&&t.uploadedId&&Number.isFinite(t.width)&&t.width>0&&Number.isFinite(t.height)&&t.height>0).map(t=>({source:"existing",url:t.url,urls:t.urls,height:t.height,width:t.width,uploadedId:t.uploadedId,orientation:t.width>t.height?"landscape":"portrait"})),this._uploadState=new WeakMap}}connectedCallback(){super.connectedCallback(),this._resizeObserver.observe(this)}disconnectedCallback(){super.disconnectedCallback(),this._resizeObserver.disconnect(),this._clearDragState(),clearTimeout(this._noticeTimer),this._selectionGeneration++,this._releaseSelectedImages()}_getPreviewIndex(e){const t=this.shadowRoot?.querySelectorAll("esp-image-preview");if(!t)return null;for(const i of e.composedPath())if(i instanceof HTMLElement&&i.tagName==="ESP-IMAGE-PREVIEW"){for(let n=0;n<t.length;n++)if(t[n]===i)return n}return null}_clearDragState(){document.removeEventListener("pointermove",this._onDocPointerMove),document.removeEventListener("pointerup",this._onDocPointerUp),document.removeEventListener("pointercancel",this._onDocPointerUp),this._dragActive&&(this._cachedPreviews&&this._dragSourceIndex!==null&&this._dragSourceIndex<this._cachedPreviews.length&&(this._cachedPreviews[this._dragSourceIndex].el.style.opacity=""),this._clearDropTargets(),document.body.style.userSelect=this._savedBodyUserSelect,this.previewsDiv.value&&(this.previewsDiv.value.style.touchAction="")),this._ghostEl?.remove(),this._ghostEl=null,this._cachedPreviews=null,this._lastDropHit=null,this._dragPointerId=null,this._dragSourceIndex=null,this._dragOverIndex=null,this._dragActive=!1}_createGhost(e,t){const i=this.shadowRoot?.querySelectorAll("esp-image-preview");if(!i||this._dragSourceIndex===null)return;const n=i[this._dragSourceIndex],s=n.getBoundingClientRect(),l=document.createElement("div"),r=Math.min(120/s.width,120/s.height),o=s.width*r,a=s.height*r;l.style.cssText=`
|
|
8
8
|
position: fixed;
|
|
9
9
|
left: 0;
|
|
10
10
|
top: 0;
|
|
@@ -19,7 +19,7 @@ var g=function(v,e,t,r){var n=arguments.length,s=n<3?e:r===null?r=Object.getOwnP
|
|
|
19
19
|
opacity: 0.85;
|
|
20
20
|
will-change: transform;
|
|
21
21
|
transform: translate(${e-o/2}px, ${t-a/2}px);
|
|
22
|
-
`;const d=n.shadowRoot?.querySelector("img");d&&(l.style.backgroundImage=`url(${d.src})`),document.body.appendChild(l),this._ghostEl=l,this._ghostHalfW=o/2,this._ghostHalfH=a/2}_updateDropTargets(e,t,
|
|
22
|
+
`;const d=n.shadowRoot?.querySelector("img");d&&(l.style.backgroundImage=`url(${d.src})`),document.body.appendChild(l),this._ghostEl=l,this._ghostHalfW=o/2,this._ghostHalfH=a/2}_updateDropTargets(e,t,i){for(let d=0;d<e.length;d++){const h=e[d];d===t&&d!==this._dragSourceIndex?h.setAttribute("data-drop-side",i?"right":"left"):h.removeAttribute("data-drop-side")}if(t===this._dragSourceIndex){this._arrowEl&&(this._arrowEl.style.display="none");return}const n=this._cachedPreviews,s=n?n[t].rect:e[t].getBoundingClientRect(),l=i?C:k;if(!this._arrowEl){const d=document.createElement("div");d.style.cssText=`
|
|
23
23
|
position: fixed;
|
|
24
24
|
left: 0;
|
|
25
25
|
top: 0;
|
|
@@ -30,27 +30,27 @@ var g=function(v,e,t,r){var n=arguments.length,s=n<3?e:r===null?r=Object.getOwnP
|
|
|
30
30
|
justify-content: center;
|
|
31
31
|
will-change: transform;
|
|
32
32
|
filter: drop-shadow(0 1px 3px rgba(0,0,0,0.4));
|
|
33
|
-
`,document.body.appendChild(d),this._arrowEl=d;const h=e[t],
|
|
33
|
+
`,document.body.appendChild(d),this._arrowEl=d;const h=e[t],u=getComputedStyle(h).getPropertyValue("--esp-color-complementary").trim();this._arrowColor=u?`oklch(from ${u} var(--esp-l-accent) c h)`:"oklch(0.7 0.2 330)"}this._arrowEl.innerHTML=l;const r=this._arrowEl.querySelector("svg");r&&(r.style.width="40px",r.style.height="40px",r.style.color=this._arrowColor??"oklch(0.7 0.2 330)"),this._arrowEl.style.display="flex";const o=i?s.left+s.width*.75:s.left+s.width*.25,a=s.top+s.height/2;this._arrowEl.style.transform=`translate(${o-20}px, ${a-20}px)`}_clearDropTargets(){const e=this.shadowRoot?.querySelectorAll("esp-image-preview");if(e)for(const t of e)t.removeAttribute("data-drop-side");this._arrowEl?.remove(),this._arrowEl=null,this._arrowColor=null}getContainerWidth(){const e=this.parentElement??this.offsetParent,t=e?e.getBoundingClientRect().width:window.innerWidth;if(t<=0){const i=window.innerWidth;return i<640?i-32:i<1024?i*90/100-32:Math.min(i*85/100-32,1400)}if(this._chromeWidth===null){const i=this.previewsDiv.value;if(i){const n=a=>{const d=parseFloat(a);return Number.isFinite(d)?d:0},s=getComputedStyle(i),l=n(s.paddingLeft)+n(s.paddingRight),r=this.shadowRoot?.querySelector(".esp-field"),o=r?n(getComputedStyle(r).borderLeftWidth)+n(getComputedStyle(r).borderRightWidth):0;this._chromeWidth=l+o}}return Math.max(t-(this._chromeWidth??0),1)}_isAccepted(e){const t=this.accept.split(",").map(s=>s.trim().toLowerCase()).filter(Boolean);if(!t.length)return e.type.toLowerCase().startsWith("image/");const i=e.type.toLowerCase(),n=e.name.toLowerCase();return t.some(s=>s.startsWith(".")?n.endsWith(s):s.endsWith("/*")?i.startsWith(s.slice(0,-1)):i===s)}_addSelectedImage(e,t,i){e[t]=i;const n=[...this.uploadedImages];let s=-1;for(let r=t-1;r>=0&&s<0;r--){const o=e[r];if(!o)continue;const a=n.indexOf(o);a>=0&&(s=a+1)}for(let r=t+1;r<e.length&&s<0;r++){const o=e[r];if(!o)continue;const a=n.indexOf(o);a>=0&&(s=a)}s<0&&(s=n.length),n.splice(s,0,i);const l=new AbortController;this._uploadState.set(i,{progress:null,failed:!1,controller:l}),this.uploadedImages=n,this.dispatchEvent(new CustomEvent(f.IMAGE_UPLOAD_FILE_SELECTED,{detail:{image:i,signal:l.signal,...this._makeCallbacks(i)},bubbles:!0,composed:!0}))}_reportRejectedFiles(e){this.dispatchEvent(new CustomEvent(f.IMAGE_UPLOAD_FILES_REJECTED,{detail:e,bubbles:!0,composed:!0}));const t=n=>n===1?"file":"files",i=[];e.unsupported.length&&i.push(`${e.unsupported.length} unsupported ${t(e.unsupported.length)} skipped`),e.unreadable.length&&i.push(`${e.unreadable.length} ${t(e.unreadable.length)} could not be read`),this._rejectionNotice=i.join("; "),clearTimeout(this._noticeTimer),this._noticeTimer=setTimeout(()=>{this._rejectionNotice=""},L)}_previewUrlFor(e,t){if(e.source!=="selected")return this._pickExistingPreviewUrl(e,t);const i=Math.min(globalThis.devicePixelRatio||1,2),n=E*i;if(t*i<=n*_._THUMBNAIL_UPSCALE_SLACK||e.height<=n)return e.url;let r=this._fullPreviewUrls.get(e);return r||(r=URL.createObjectURL(e.file),this._fullPreviewUrls.set(e,r)),r}_pickExistingPreviewUrl(e,t){const i=e.urls;if(!i?.length)return e.url;const n=Math.min(globalThis.devicePixelRatio||1,2),s=e.height>0?e.width/e.height:1,l=t*s*n,r=[...i].sort((a,d)=>a.minWidth-d.minWidth);return(r.find(a=>a.minWidth>=l)??r[r.length-1]).url}_releaseFullPreviewUrl(e){if(e.source!=="selected")return;const t=this._fullPreviewUrls.get(e);t&&(URL.revokeObjectURL(t),this._fullPreviewUrls.delete(e))}_releaseSelectedImages(){for(const e of this.uploadedImages)e.source==="selected"&&(this._uploadState.get(e)?.controller.abort(),I(e));for(const e of this._fullPreviewUrls.values())URL.revokeObjectURL(e);this._fullPreviewUrls.clear()}render(){const{draggingOver:e,uploadedImages:t}=this,i={"dragging-over":e,"has-previews":t.length},n=this.getContainerWidth(),s=window.innerHeight>0?window.innerHeight/2:Number.POSITIVE_INFINITY,l=M(t,n,E,8,s,this.maxImagesPerRow);return m` <div
|
|
34
34
|
class="esp-field"
|
|
35
35
|
@click=${()=>{this.dropAreaDiv.value?.focus({preventScroll:!0})}}
|
|
36
|
-
@dragover=${
|
|
37
|
-
@dragleave=${
|
|
38
|
-
@drop=${
|
|
36
|
+
@dragover=${r=>{r.preventDefault(),this.draggingOver=!0}}
|
|
37
|
+
@dragleave=${r=>{r.preventDefault(),this.draggingOver=!1}}
|
|
38
|
+
@drop=${r=>{r.preventDefault(),this.draggingOver=!1;const o=r.dataTransfer?.files;o&&o.length&&this.filesSelected(o)}}
|
|
39
39
|
>
|
|
40
40
|
<div
|
|
41
41
|
${x(this.previewsDiv)}
|
|
42
|
-
class=${
|
|
42
|
+
class=${y({previews:!0,...i})}
|
|
43
43
|
@pointerdown=${this._handleDragPointerDown}
|
|
44
44
|
>
|
|
45
|
-
${l.map(
|
|
46
|
-
${
|
|
45
|
+
${l.map(r=>m`<div class="photo-row" style="height: ${r.height}px;">
|
|
46
|
+
${r.images.map(o=>{const a=r.height,d=o.width/o.height*a,h=this._uploadState.get(o);return m`<esp-image-preview
|
|
47
47
|
style="width: ${d}px; height: ${a}px; flex-shrink: 0;"
|
|
48
48
|
.url=${this._previewUrlFor(o,a)}
|
|
49
49
|
.alt=${o.source==="selected"?o.file.name:""}
|
|
50
50
|
.progress=${h?.progress}
|
|
51
51
|
.failed=${h?.failed??!1}
|
|
52
|
-
@esp-internal-image-preview-remove=${()=>{const c=this.uploadedImages.indexOf(o);if(c<0)return;this._uploadState.get(o)?.controller.abort(),this._uploadState.delete(o),I(o),this._releaseFullPreviewUrl(o);const
|
|
53
|
-
@esp-internal-image-preview-retry=${()=>{if(o.source!=="selected")return;const c=new AbortController,
|
|
52
|
+
@esp-internal-image-preview-remove=${()=>{const c=this.uploadedImages.indexOf(o);if(c<0)return;this._uploadState.get(o)?.controller.abort(),this._uploadState.delete(o),I(o),this._releaseFullPreviewUrl(o);const u=[...this.uploadedImages];u.splice(c,1),this.uploadedImages=u,this.dispatchEvent(new CustomEvent(f.IMAGE_UPLOAD_FILE_REMOVED,{detail:o,bubbles:!0,composed:!0}))}}
|
|
53
|
+
@esp-internal-image-preview-retry=${()=>{if(o.source!=="selected")return;const c=new AbortController,u=this._uploadState.get(o);u?(u.failed=!1,u.progress=null,u.controller=c):this._uploadState.set(o,{progress:null,failed:!1,controller:c}),this.requestUpdate(),this.dispatchEvent(new CustomEvent(f.IMAGE_UPLOAD_RETRY,{detail:{image:o,signal:c.signal,...this._makeCallbacks(o)},bubbles:!0,composed:!0}))}}
|
|
54
54
|
></esp-image-preview>`})}
|
|
55
55
|
</div>`)}
|
|
56
56
|
</div>
|
|
@@ -59,9 +59,9 @@ var g=function(v,e,t,r){var n=arguments.length,s=n<3?e:r===null?r=Object.getOwnP
|
|
|
59
59
|
tabindex="0"
|
|
60
60
|
role="button"
|
|
61
61
|
aria-label="Add photos"
|
|
62
|
-
class=${
|
|
62
|
+
class=${y({"drop-area":!0,...i})}
|
|
63
63
|
@click=${()=>{this.uploadInput.value?.click()}}
|
|
64
|
-
@keydown=${
|
|
64
|
+
@keydown=${r=>{(r.code==="Enter"||r.code==="Space")&&(r.preventDefault(),this.uploadInput.value?.click())}}
|
|
65
65
|
>
|
|
66
66
|
<svg
|
|
67
67
|
xmlns="http://www.w3.org/2000/svg"
|
|
@@ -109,9 +109,9 @@ var g=function(v,e,t,r){var n=arguments.length,s=n<3?e:r===null?r=Object.getOwnP
|
|
|
109
109
|
multiple
|
|
110
110
|
accept=${this.accept}
|
|
111
111
|
hidden
|
|
112
|
-
@change=${()=>{const
|
|
112
|
+
@change=${()=>{const r=this.uploadInput.value;!r||!r.files||!r.files.length||(this.filesSelected(r.files),r.value="")}}
|
|
113
113
|
/>
|
|
114
|
-
</div>`}};
|
|
114
|
+
</div>`}};p._DRAG_THRESHOLD=8,p._THUMBNAIL_UPSCALE_SLACK=1.1,p.styles=[...P.styles,D`
|
|
115
115
|
:host {
|
|
116
116
|
overflow: hidden;
|
|
117
117
|
}
|
|
@@ -237,4 +237,4 @@ var g=function(v,e,t,r){var n=arguments.length,s=n<3?e:r===null?r=Object.getOwnP
|
|
|
237
237
|
}
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
|
-
`],g([w()],
|
|
240
|
+
`],g([w()],p.prototype,"draggingOver",void 0),g([w()],p.prototype,"uploadedImages",void 0),g([S({type:String})],p.prototype,"accept",void 0),g([S({attribute:"max-images-per-row",type:Number})],p.prototype,"maxImagesPerRow",void 0),g([w()],p.prototype,"_rejectionNotice",void 0),p=_=g([A("esp-image-upload")],p);export{p as EspalierImageUpload};
|
package/dist/index.d.ts
CHANGED
|
@@ -71,7 +71,7 @@ export { requestHelp, type HelpRequest, type HelpState } from "./shared/help-eve
|
|
|
71
71
|
export { getEspBus, type EspBusEventMap, type SchemeEvents, type ToastEvents, type FlyoutEvents, type HelpEvents, type PopoverEvents, type SizeEvents, type PageEventMap, type SeedColorRoot, } from "./shared/bus-events.js";
|
|
72
72
|
export * from "./shared/events.js";
|
|
73
73
|
export { getImageDetails, releasePreviewUrl, type EspalierUploadImage, type ImageDetailsOptions, type SelectedUploadImage, type ExistingUploadImage, type ExistingImage, type ResponsiveImageUrl, type UploadCallbacks, type UploadEventDetail, } from "./image-upload/image-helpers.js";
|
|
74
|
-
export { calculatePhotoLayout, type LayoutImage, type PhotoRow, } from "./shared/justified-layout.js";
|
|
74
|
+
export { calculatePhotoLayout, normalizeMaxImagesPerRow, type LayoutImage, type PhotoRow, } from "./shared/justified-layout.js";
|
|
75
75
|
export { type TypeaheadFetchItems } from "./pickers/types.js";
|
|
76
76
|
export { type EspalierTheme, type LightnessKey, type LightnessReference, type PartialTheme, type PartialThemeContexts, type PartialThemeTones, type ThemeContext, type ThemeContexts, type ThemeTones, type ToneReference, type VariantColorSource, encodeTheme, parseTheme, mergePartials, layerThemes, validateThemePair, resolveContextTheme, isObjectRecord, isSemanticColorName, buildTaprootLightTheme, buildTaprootDarkTheme, NESTED_THEME_KEYS, } from "./shared/theme.js";
|
|
77
77
|
export { auditDataPalette, describePaletteCollision, generateSequentialRamp, generateDivergingRamp, COLOR_VISION_SIMULATIONS, DATA_SERIES_KEYS, DEFAULT_DATA_PALETTE, DEFAULT_DATA_RAMP_STEPS, DEFAULT_DIVERGING_NEUTRAL, MAX_DATA_RAMP_STEPS, MIN_DATA_COLOR_DISTANCE, MIN_DATA_RAMP_LIGHTNESS_STEP, MIN_DATA_RAMP_STEPS, type ColorVisionSimulation, type DataPalette, type DataPaletteIssue, type DataRamp, type DataRamps, type DataSeriesKey, type DivergingDataRamp, type DivergingRampOptions, type PartialDataRamp, type PartialDataRamps, type SequentialDataRamp, type SequentialRampOptions, } from "./shared/data-colors.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./box/esp-box.js";export*from"./action-menu/esp-action-menu.js";export*from"./action-menu/esp-action-menu-item.js";export*from"./avatar/esp-avatar.js";export*from"./avatar/esp-profile-chip.js";export*from"./badge/esp-badge.js";export*from"./checkbox/esp-checkbox.js";export*from"./checkbox/esp-checkbox-group.js";export*from"./data-cell/esp-data-cell.js";export*from"./radio-button/esp-radio-button.js";export*from"./radio-button/esp-radio-button-group.js";export*from"./repeater/esp-repeater.js";export*from"./breadcrumbs/esp-breadcrumbs.js";export*from"./button/esp-button.js";export*from"./button/esp-button-group.js";export*from"./color-picker/esp-color-picker.js";export*from"./flyout/esp-flyout.js";export*from"./form/esp-form.js";export*from"./form-item/esp-form-item.js";export*from"./help/esp-help-button.js";export*from"./help/esp-help-provider.js";export*from"./header/index.js";export*from"./page/esp-page.js";export*from"./section/esp-section.js";export*from"./stack/esp-stack.js";export*from"./row/esp-row.js";export*from"./popover/esp-popover.js";export*from"./dialog/esp-dialog.js";export*from"./empty-state/esp-empty-state.js";export*from"./image-upload/esp-image-upload.js";export*from"./file-upload/esp-file-upload.js";export*from"./font-picker/esp-font-picker.js";export*from"./focus-picker/esp-focus-picker.js";export*from"./footer/index.js";export*from"./grid/esp-grid.js";export*from"./image/esp-image.js";export*from"./image/image-focus.js";export*from"./lightbox/esp-lightbox.js";export*from"./info/esp-info.js";export*from"./input/esp-input.js";export*from"./textarea/esp-textarea.js";export*from"./pickers/esp-pick-one.js";export*from"./pickers/esp-pick-some.js";export*from"./pickers/esp-picker-menu.js";export*from"./pickers/esp-picker-item.js";export*from"./root/esp-root.js";export*from"./menu/index.js";export*from"./burger/esp-burger.js";export*from"./date-picker/esp-date-picker.js";export*from"./details/esp-details.js";export*from"./details/esp-details-group.js";export*from"./tabs/esp-tab.js";export*from"./tabs/esp-tab-group.js";export*from"./slider/esp-slider.js";export*from"./switch/esp-switch.js";export*from"./toaster/esp-toaster.js";export*from"./tooltip/esp-tooltip.js";export*from"./progress/esp-progress.js";export*from"./search/esp-search.js";export*from"./status-indicator/esp-status-indicator.js";export*from"./tree/esp-tree.js";export*from"./tree/esp-tree-item.js";import{DEFAULT_ICON_SPRITE_URL as _o,DEFAULT_ICON_VIEW_BOX as Io,INTENT_VARIANTS as ao,normalizeIntentVariant as io,getIconHrefForHost as lo,getIconSpriteUrl as Fo,getIconSpriteReference as
|
|
1
|
+
export*from"./box/esp-box.js";export*from"./action-menu/esp-action-menu.js";export*from"./action-menu/esp-action-menu-item.js";export*from"./avatar/esp-avatar.js";export*from"./avatar/esp-profile-chip.js";export*from"./badge/esp-badge.js";export*from"./checkbox/esp-checkbox.js";export*from"./checkbox/esp-checkbox-group.js";export*from"./data-cell/esp-data-cell.js";export*from"./radio-button/esp-radio-button.js";export*from"./radio-button/esp-radio-button-group.js";export*from"./repeater/esp-repeater.js";export*from"./breadcrumbs/esp-breadcrumbs.js";export*from"./button/esp-button.js";export*from"./button/esp-button-group.js";export*from"./color-picker/esp-color-picker.js";export*from"./flyout/esp-flyout.js";export*from"./form/esp-form.js";export*from"./form-item/esp-form-item.js";export*from"./help/esp-help-button.js";export*from"./help/esp-help-provider.js";export*from"./header/index.js";export*from"./page/esp-page.js";export*from"./section/esp-section.js";export*from"./stack/esp-stack.js";export*from"./row/esp-row.js";export*from"./popover/esp-popover.js";export*from"./dialog/esp-dialog.js";export*from"./empty-state/esp-empty-state.js";export*from"./image-upload/esp-image-upload.js";export*from"./file-upload/esp-file-upload.js";export*from"./font-picker/esp-font-picker.js";export*from"./focus-picker/esp-focus-picker.js";export*from"./footer/index.js";export*from"./grid/esp-grid.js";export*from"./image/esp-image.js";export*from"./image/image-focus.js";export*from"./lightbox/esp-lightbox.js";export*from"./info/esp-info.js";export*from"./input/esp-input.js";export*from"./textarea/esp-textarea.js";export*from"./pickers/esp-pick-one.js";export*from"./pickers/esp-pick-some.js";export*from"./pickers/esp-picker-menu.js";export*from"./pickers/esp-picker-item.js";export*from"./root/esp-root.js";export*from"./menu/index.js";export*from"./burger/esp-burger.js";export*from"./date-picker/esp-date-picker.js";export*from"./details/esp-details.js";export*from"./details/esp-details-group.js";export*from"./tabs/esp-tab.js";export*from"./tabs/esp-tab-group.js";export*from"./slider/esp-slider.js";export*from"./switch/esp-switch.js";export*from"./toaster/esp-toaster.js";export*from"./tooltip/esp-tooltip.js";export*from"./progress/esp-progress.js";export*from"./search/esp-search.js";export*from"./status-indicator/esp-status-indicator.js";export*from"./tree/esp-tree.js";export*from"./tree/esp-tree-item.js";import{DEFAULT_ICON_SPRITE_URL as _o,DEFAULT_ICON_VIEW_BOX as Io,INTENT_VARIANTS as ao,normalizeIntentVariant as io,getIconHrefForHost as lo,getIconSpriteUrl as Fo,getIconSpriteReference as no}from"./shared/intent-values.js";import{EspalierElementBase as So}from"./shared/esp-element-base.js";import{VALIDITY_CHANGED_EVENT as Lo}from"./shared/validation.js";import{FormFieldController as Do}from"./shared/form-field-controller.js";import{traverseToClosest as go}from"./shared/utilities.js";import{showToast as co}from"./shared/toast-events.js";import{showFlyout as Mo,closeFlyout as Oo}from"./shared/flyout-events.js";import{requestHelp as Co}from"./shared/help-events.js";import{getEspBus as Uo}from"./shared/bus-events.js";export*from"./shared/events.js";import{getImageDetails as vo,releasePreviewUrl as yo}from"./image-upload/image-helpers.js";import{calculatePhotoLayout as ko,normalizeMaxImagesPerRow as Wo}from"./shared/justified-layout.js";import{encodeTheme as Bo,parseTheme as zo,mergePartials as Ko,layerThemes as qo,validateThemePair as Xo,resolveContextTheme as Yo,isObjectRecord as jo,isSemanticColorName as Jo,buildTaprootLightTheme as Qo,buildTaprootDarkTheme as Zo,NESTED_THEME_KEYS as $o}from"./shared/theme.js";import{auditDataPalette as ee,describePaletteCollision as re,generateSequentialRamp as te,generateDivergingRamp as me,COLOR_VISION_SIMULATIONS as pe,DATA_SERIES_KEYS as Te,DEFAULT_DATA_PALETTE as fe,DEFAULT_DATA_RAMP_STEPS as xe,DEFAULT_DIVERGING_NEUTRAL as Ee,MAX_DATA_RAMP_STEPS as _e,MIN_DATA_COLOR_DISTANCE as Ie,MIN_DATA_RAMP_LIGHTNESS_STEP as ae,MIN_DATA_RAMP_STEPS as ie}from"./shared/data-colors.js";import{WEIGHT_LABELS as Fe,extractWeights as ne,normalizeWeight as Ae,bestAvailableWeight as Se,extractFamily as se,getFallbackFont as Le,googleFontStylesheetUrl as Re,isLocalFontFamily as De,normalizeFontFaceWeight as Ne,removeRuntimeGoogleFontLink as ge,removeRuntimeGoogleFontLinks as Pe,syncRuntimeGoogleFontLink as ce,RUNTIME_GOOGLE_FONT_OWNER_ATTR as he}from"./shared/font-helpers.js";import{compileFontPlan as Oe,fontFallbackAliases as He,fontFallbackBaseIndexes as Ce,fontFaceRequestKey as ue}from"./shared/font-plan.js";import{getGoogleFonts as Ge}from"./font-picker/esp-font-picker.js";import{ROOT_SURFACE as be,THEME_FIT_ANCHOR_FIELDS as ve,THEME_FIT_APCA_FIELDS as ye,THEME_FIT_DATA_PALETTE_LINT_FIELDS as Ve,THEME_FIT_DATA_PALETTE_LINT_IDS as ke,THEME_FIT_EXPLICIT_VALUES as We,THEME_FIT_LINT_FIELDS as we,THEME_FIT_LINT_IDS as Be,THEME_FIT_LINT_SEVERITIES as ze,THEME_FIT_REPORT_FIELDS as Ke,THEME_FIT_SUITE_FIELDS as qe,THEME_FIT_TOKEN_FIELDS as Xe,themeFitReport as Ye,themeFitRows as je,themeFitLints as Je,themeFitReportSuite as Qe,printThemeFitReport as Ze}from"./shared/theme-fit-report.js";import{ICON_SPRITE as or,ICON_SPRITE_ID as er,installIconSprite as rr}from"./icons/index.js";import{deriveLightnessRamp as mr,themeFromSwatches as pr}from"./shared/theme-swatches.js";export{pe as COLOR_VISION_SIMULATIONS,Te as DATA_SERIES_KEYS,fe as DEFAULT_DATA_PALETTE,xe as DEFAULT_DATA_RAMP_STEPS,Ee as DEFAULT_DIVERGING_NEUTRAL,_o as DEFAULT_ICON_SPRITE_URL,Io as DEFAULT_ICON_VIEW_BOX,So as EspalierElementBase,Do as FormFieldController,or as ICON_SPRITE,er as ICON_SPRITE_ID,ao as INTENT_VARIANTS,_e as MAX_DATA_RAMP_STEPS,Ie as MIN_DATA_COLOR_DISTANCE,ae as MIN_DATA_RAMP_LIGHTNESS_STEP,ie as MIN_DATA_RAMP_STEPS,$o as NESTED_THEME_KEYS,be as ROOT_SURFACE,he as RUNTIME_GOOGLE_FONT_OWNER_ATTR,ve as THEME_FIT_ANCHOR_FIELDS,ye as THEME_FIT_APCA_FIELDS,Ve as THEME_FIT_DATA_PALETTE_LINT_FIELDS,ke as THEME_FIT_DATA_PALETTE_LINT_IDS,We as THEME_FIT_EXPLICIT_VALUES,we as THEME_FIT_LINT_FIELDS,Be as THEME_FIT_LINT_IDS,ze as THEME_FIT_LINT_SEVERITIES,Ke as THEME_FIT_REPORT_FIELDS,qe as THEME_FIT_SUITE_FIELDS,Xe as THEME_FIT_TOKEN_FIELDS,Lo as VALIDITY_CHANGED_EVENT,Fe as WEIGHT_LABELS,ee as auditDataPalette,Se as bestAvailableWeight,Zo as buildTaprootDarkTheme,Qo as buildTaprootLightTheme,ko as calculatePhotoLayout,Oo as closeFlyout,Oe as compileFontPlan,mr as deriveLightnessRamp,re as describePaletteCollision,Bo as encodeTheme,se as extractFamily,ne as extractWeights,ue as fontFaceRequestKey,He as fontFallbackAliases,Ce as fontFallbackBaseIndexes,me as generateDivergingRamp,te as generateSequentialRamp,Uo as getEspBus,Le as getFallbackFont,Ge as getGoogleFonts,lo as getIconHrefForHost,no as getIconSpriteReference,Fo as getIconSpriteUrl,vo as getImageDetails,Re as googleFontStylesheetUrl,rr as installIconSprite,De as isLocalFontFamily,jo as isObjectRecord,Jo as isSemanticColorName,qo as layerThemes,Ko as mergePartials,Ne as normalizeFontFaceWeight,io as normalizeIntentVariant,Wo as normalizeMaxImagesPerRow,Ae as normalizeWeight,zo as parseTheme,Ze as printThemeFitReport,yo as releasePreviewUrl,ge as removeRuntimeGoogleFontLink,Pe as removeRuntimeGoogleFontLinks,Co as requestHelp,Yo as resolveContextTheme,Mo as showFlyout,co as showToast,ce as syncRuntimeGoogleFontLink,Je as themeFitLints,Ye as themeFitReport,Qe as themeFitReportSuite,je as themeFitRows,pr as themeFromSwatches,go as traverseToClosest,Xo as validateThemePair};
|
|
@@ -17,6 +17,17 @@ export interface PhotoRow<T extends LayoutImage = LayoutImage> {
|
|
|
17
17
|
images: T[];
|
|
18
18
|
height: number;
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Resolve a consumer-provided image-row ceiling to a usable positive integer.
|
|
22
|
+
* Values outside `1…maximum`, including non-numbers and non-finite values,
|
|
23
|
+
* return `fallback`. The default fallback and maximum leave row lengths
|
|
24
|
+
* unlimited.
|
|
25
|
+
*
|
|
26
|
+
* @param value Consumer-provided row ceiling to validate
|
|
27
|
+
* @param fallback Value returned when `value` is invalid
|
|
28
|
+
* @param maximum Largest accepted row ceiling
|
|
29
|
+
*/
|
|
30
|
+
export declare function normalizeMaxImagesPerRow(value: unknown, fallback?: number, maximum?: number): number;
|
|
20
31
|
/**
|
|
21
32
|
* Compute justified layout rows for a list of images.
|
|
22
33
|
*
|
|
@@ -39,5 +50,8 @@ export interface PhotoRow<T extends LayoutImage = LayoutImage> {
|
|
|
39
50
|
* @param gap Horizontal gap in px between images within a row
|
|
40
51
|
* @param maxRowHeight Ceiling for row heights — keeps a stretched final row
|
|
41
52
|
* (or a single image) from ballooning past e.g. half the viewport height
|
|
53
|
+
* @param maxImagesPerRow Optional positive-integer ceiling for the number of
|
|
54
|
+
* images in each row. Omit it, or pass an invalid value, for an unlimited row
|
|
55
|
+
* length.
|
|
42
56
|
*/
|
|
43
|
-
export declare function calculatePhotoLayout<T extends LayoutImage>(images: T[], containerWidth: number, targetRowHeight?: number, gap?: number, maxRowHeight?: number): PhotoRow<T>[];
|
|
57
|
+
export declare function calculatePhotoLayout<T extends LayoutImage>(images: T[], containerWidth: number, targetRowHeight?: number, gap?: number, maxRowHeight?: number, maxImagesPerRow?: number): PhotoRow<T>[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
function w(n,I=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY){return typeof n=="number"&&Number.isInteger(n)&&n>0&&n<=o?n:I}function b(n,I,o=220,i=8,m=Number.POSITIVE_INFINITY,p=Number.POSITIVE_INFINITY){if(n.length===0)return[];const d=w(p),u=e=>e.reduce((r,h)=>r+h.width/h.height,0),s=e=>{const r=(e.length-1)*i;return(I-r)/u(e)},N=e=>e>o?e/o:o/e,l=[];let t=[];const c=(e,r)=>{l.push({images:[...e],height:Math.min(r,m)})};for(let e=0;e<n.length;e++){t.push(n[e]);const h=u(t)*o+(t.length-1)*i>I,g=e===n.length-1;if(h&&t.length>1){const T=s(t),f=s(t.slice(0,-1));N(T)<=N(f)?c(t,T):(t.pop(),e--,c(t,f)),t=[]}else t.length>=d?(c(t,s(t)),t=[]):g&&(c(t,s(t)),t=[])}return l}export{b as calculatePhotoLayout,w as normalizeMaxImagesPerRow};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taprootio/espalier",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.10.0",
|
|
4
4
|
"packageManager": "bun@1.3.12",
|
|
5
5
|
"description": "Espalier — a themeable, accessible, framework-agnostic, enterprise-grade design system built on web standards and love.",
|
|
6
6
|
"customElements": "custom-elements.json",
|