@taprootio/espalier 2.7.1 → 2.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.
- package/CHANGELOG.md +18 -0
- package/custom-elements.json +2926 -2859
- package/dist/popover/esp-popover.d.ts +29 -4
- package/dist/popover/esp-popover.js +6 -6
- package/dist/shared/popover-controller.js +1 -1
- package/package.json +1 -1
|
@@ -54,10 +54,12 @@ export declare class EspalierPopover extends LitElement {
|
|
|
54
54
|
*/
|
|
55
55
|
readonly popoverId: string;
|
|
56
56
|
/**
|
|
57
|
-
* Attach determines which side of the target the
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
57
|
+
* Attach determines which side of the target the popover will appear on.
|
|
58
|
+
* With the default `collision="flip"`, the popover tries the specified side
|
|
59
|
+
* first but may use the opposite side when it has more room. Use
|
|
60
|
+
* `collision="shift"` to preserve this requested side while shifting the
|
|
61
|
+
* panel into the viewport, or `collision="none"` to disable adjustment.
|
|
62
|
+
* It can be one of the following:
|
|
61
63
|
*
|
|
62
64
|
* #### Place above
|
|
63
65
|
*
|
|
@@ -104,6 +106,29 @@ export declare class EspalierPopover extends LitElement {
|
|
|
104
106
|
* ```
|
|
105
107
|
*/
|
|
106
108
|
attach: "left" | "right" | "above" | "below";
|
|
109
|
+
/**
|
|
110
|
+
* Determines how the popover responds when its natural placement would
|
|
111
|
+
* leave the viewport:
|
|
112
|
+
*
|
|
113
|
+
* - `"flip"` moves the popover to the opposite side when that side has
|
|
114
|
+
* more room, then constrains it horizontally. This is the default and
|
|
115
|
+
* preserves the existing behavior.
|
|
116
|
+
* - `"shift"` keeps the requested `attach` side and shifts the popover
|
|
117
|
+
* within the viewport. Oversized panels are pinned to the viewport's
|
|
118
|
+
* top or left edge and may overlap content beyond the trigger.
|
|
119
|
+
* - `"none"` keeps the requested side without viewport adjustment.
|
|
120
|
+
*
|
|
121
|
+
* Use `shift` when the attachment side conveys meaning and a partial
|
|
122
|
+
* overlap is preferable to flipping the panel:
|
|
123
|
+
*
|
|
124
|
+
* ```html
|
|
125
|
+
* <esp-popover attach="above" collision="shift">
|
|
126
|
+
* <esp-button label="Banner settings" slot="target"></esp-button>
|
|
127
|
+
* <esp-box slot="popover">Settings stay attached above.</esp-box>
|
|
128
|
+
* </esp-popover>
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
collision: "flip" | "shift" | "none";
|
|
107
132
|
/**
|
|
108
133
|
* Align determines how the popover is aligned relative
|
|
109
134
|
* to the target. For example, if attach is "below" and align
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
1
|
+
var n=function(u,t,e,r){var o=arguments.length,i=o<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,e):r,h;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(u,t,e,r);else for(var s=u.length-1;s>=0;s--)(h=u[s])&&(i=(o<3?h(i):o>3?h(t,e,i):h(t,e))||i);return o>3&&i&&Object.defineProperty(t,e,i),i};import{LitElement as b,css as T,html as w}from"lit";import{customElement as D,property as a,state as P}from"lit/decorators.js";import{createRef as g,ref as m}from"lit/directives/ref.js";import{findContainingPopovers as y,PopoverController as O}from"../shared/popover-controller.js";import{alignAttributeTextInheritance as C}from"../shared/style-fragments.js";let $=0,l=class extends b{constructor(){super(...arguments),this.popoverOpen=!1,this.thePopover=g(),this.popoverSlot=g(),this.targetSlot=g(),this.attachTo=null,this.showDelayTimer=null,this.hideDelayTimer=null,this.isHovered=!1,this.isFocused=!1,this.collisionRafId=0,this.popoverId=`esp-popover-${++$}`,this.popoverCtrl=new O({host:this,closeStrategy:"skip-list",isOpen:()=>this.popoverOpen,onShouldClose:()=>this.closePopover(),onPositionUpdate:()=>this.positionPopover(),getPositionElements:()=>[this.attachTo,this.thePopover.value],getInsideElements:()=>[this.thePopover.value??null],onOutsideClick:()=>this.closePopover()}),this.attach="below",this.collision="flip",this.align="start",this.offset="",this.offsetX=0,this.offsetY=0,this.trigger="click",this.showDelay=0,this.hideDelay=0,this.closePopover=()=>{this.cancelDelays(),this.cancelCollisionAdjustment();const t=this.thePopover.value;if(t&&this.popoverOpen)try{t.hidePopover()}catch{}this.popoverCtrl.stopTracking(),this.popoverCtrl.stopOutsideClick(),this.popoverOpen&&(this.popoverOpen=!1,this.dispatchEvent(new CustomEvent("popover-closed",{bubbles:!0,composed:!0})))},this.openPopover=()=>{this.scheduleOpen()},this.updatePosition=()=>{this.popoverOpen&&this.positionPopover()},this.toggleOpen=t=>{this.trigger==="click"&&(t.stopPropagation(),this.popoverOpen?this.closePopover():this.doOpen())}}cancelDelays(){this.showDelayTimer!==null&&(clearTimeout(this.showDelayTimer),this.showDelayTimer=null),this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null)}cancelCollisionAdjustment(){this.collisionRafId&&(cancelAnimationFrame(this.collisionRafId),this.collisionRafId=0)}applyPixelOffset(t,e){if(e===0)return t;const r=t.startsWith("calc(")&&t.endsWith(")")?t.slice(5,-1):t,o=e>0?"+":"-";return`calc(${r} ${o} ${Math.abs(e)}px)`}scheduleOpen(){this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null),!this.popoverOpen&&(this.showDelay>0&&this.showDelayTimer===null?this.showDelayTimer=setTimeout(()=>{this.showDelayTimer=null,this.doOpen()},this.showDelay):this.showDelay<=0&&this.doOpen())}scheduleClose(){this.showDelayTimer!==null&&(clearTimeout(this.showDelayTimer),this.showDelayTimer=null),this.popoverOpen&&(this.hideDelay>0&&this.hideDelayTimer===null?this.hideDelayTimer=setTimeout(()=>{this.hideDelayTimer=null,this.closePopover()},this.hideDelay):this.hideDelay<=0&&this.closePopover())}doOpen(){if(this.popoverOpen)return;const t=y(this);this.popoverCtrl.publishCloseExcept(t),this.popoverOpen=!0,this.positionPopover(),this.popoverCtrl.startTracking(),this.popoverCtrl.startOutsideClick(),this.dispatchEvent(new CustomEvent("popover-opened",{bubbles:!0,composed:!0}))}positionPopover(){const t=this.thePopover.value;if(!t||!this.attachTo)return;const e=this.attachTo.getBoundingClientRect(),r=this.offset.length?this.offset:"0px";t.matches(":popover-open")||t.showPopover();const o=t.getBoundingClientRect(),i=window.innerHeight||document.documentElement.clientHeight,h=window.innerWidth||document.documentElement.clientWidth;this.cancelCollisionAdjustment();let s=this.attach;this.collision==="flip"&&(s==="above"&&e.top<o.height&&i-e.bottom>e.top?s="below":s==="below"&&i-e.bottom<o.height&&e.top>i-e.bottom?s="above":s==="left"&&e.left<o.width&&h-e.right>e.left?s="right":s==="right"&&h-e.right<o.width&&e.left>h-e.right&&(s="left"));let c="0px",f="0px";switch(s){case"above":c=`calc(${e.top-o.height}px - ${r})`;break;case"below":c=`calc(${e.bottom}px + ${r})`;break;case"left":f=`calc(${e.left-o.width}px - ${r})`;break;case"right":f=`calc(${e.right}px + ${r})`;break}if(s==="above"||s==="below")switch(this.align){case"start":f=`${e.left}px`;break;case"center":f=`${e.left+e.width/2-o.width/2}px`;break;case"end":f=`${e.right-o.width}px`;break}else switch(this.align){case"start":c=`${e.top}px`;break;case"center":c=`${e.top+e.height/2-o.height/2}px`;break;case"end":c=`${e.bottom-o.height}px`;break}f=this.applyPixelOffset(f,this.offsetX),c=this.applyPixelOffset(c,this.offsetY),t.style.top=c,t.style.left=f,this.collision!=="none"&&(this.collisionRafId=requestAnimationFrame(()=>{if(this.collisionRafId=0,!this.popoverOpen||!t.matches(":popover-open"))return;const p=t.getBoundingClientRect();let d=p.left;if(p.width>h?d=0:d=Math.min(Math.max(p.left,0),h-p.width),d!==p.left&&(t.style.left=`${d}px`),this.collision!=="shift")return;let v=p.top;p.height>i?v=0:v=Math.min(Math.max(p.top,0),i-p.height),v!==p.top&&(t.style.top=`${v}px`)}))}handleHoverEnter(){this.isHovered=!0,this.scheduleOpen()}handleHoverLeave(){if(this.isHovered=!1,this.trigger==="focus-hover"&&this.isFocused){this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null);return}this.scheduleClose()}handleFocusIn(){this.isFocused=!0,this.scheduleOpen()}handleFocusOut(){if(this.isFocused=!1,this.trigger==="focus-hover"&&this.isHovered){this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null);return}this.scheduleClose()}disconnectedCallback(){super.disconnectedCallback(),this.cancelDelays(),this.cancelCollisionAdjustment()}updated(t){t.has("trigger")&&(this.isHovered=!1,this.isFocused=!1,this.cancelDelays()),this.popoverOpen&&["attach","align","collision","offset","offsetX","offsetY"].some(e=>t.has(e))&&this.positionPopover()}firstUpdated(t){let e=this.targetSlot.value.assignedElements()[0];for(;e instanceof HTMLSlotElement;)e=e.assignedElements()[0];this.attachTo=e;const r=this.thePopover.value;r&&(r.setAttribute("popover","manual"),r.id=this.popoverId);const o=this.popoverSlot.value?.assignedElements();if(o?.length){let i=o[0];for(;i instanceof HTMLSlotElement;)i=i.assignedElements()[0];i&&(i["linked-popover"]=this,i.addEventListener("click",h=>{h.stopPropagation();const s=[this,...y(this)];this.popoverCtrl.publishCloseExcept(s)}))}}render(){return w`
|
|
2
2
|
<slot
|
|
3
|
-
${
|
|
3
|
+
${m(this.targetSlot)}
|
|
4
4
|
@click=${t=>{this.trigger==="click"&&this.toggleOpen(t)}}
|
|
5
5
|
@mouseenter=${()=>{this.trigger!=="hover"&&this.trigger!=="focus-hover"||this.handleHoverEnter()}}
|
|
6
6
|
@mouseleave=${()=>{this.trigger!=="hover"&&this.trigger!=="focus-hover"||this.handleHoverLeave()}}
|
|
@@ -9,14 +9,14 @@ var p=function(u,t,e,r){var o=arguments.length,i=o<3?t:r===null?r=Object.getOwnP
|
|
|
9
9
|
name="target"
|
|
10
10
|
></slot>
|
|
11
11
|
<div
|
|
12
|
-
${
|
|
12
|
+
${m(this.thePopover)}
|
|
13
13
|
class="popover-content"
|
|
14
14
|
@mouseenter=${()=>{this.trigger!=="hover"&&this.trigger!=="focus-hover"||(this.isHovered=!0,this.hideDelayTimer!==null&&(clearTimeout(this.hideDelayTimer),this.hideDelayTimer=null))}}
|
|
15
15
|
@mouseleave=${()=>{this.trigger!=="hover"&&this.trigger!=="focus-hover"||this.handleHoverLeave()}}
|
|
16
16
|
>
|
|
17
|
-
<slot name="popover" ${
|
|
17
|
+
<slot name="popover" ${m(this.popoverSlot)}></slot>
|
|
18
18
|
</div>
|
|
19
|
-
`}};
|
|
19
|
+
`}};l.styles=[C,T`
|
|
20
20
|
:host {
|
|
21
21
|
position: relative;
|
|
22
22
|
display: flex;
|
|
@@ -33,4 +33,4 @@ var p=function(u,t,e,r){var o=arguments.length,i=o<3?t:r===null?r=Object.getOwnP
|
|
|
33
33
|
overflow: visible;
|
|
34
34
|
color: var(--esp-color-text);
|
|
35
35
|
}
|
|
36
|
-
`],
|
|
36
|
+
`],n([P()],l.prototype,"popoverOpen",void 0),n([a({attribute:"attach",type:String})],l.prototype,"attach",void 0),n([a({attribute:"collision",type:String})],l.prototype,"collision",void 0),n([a({attribute:"align",type:String})],l.prototype,"align",void 0),n([a({attribute:"offset",type:String})],l.prototype,"offset",void 0),n([a({attribute:"offset-x",type:Number})],l.prototype,"offsetX",void 0),n([a({attribute:"offset-y",type:Number})],l.prototype,"offsetY",void 0),n([a({attribute:"trigger",type:String})],l.prototype,"trigger",void 0),n([a({attribute:"show-delay",type:Number})],l.prototype,"showDelay",void 0),n([a({attribute:"hide-delay",type:Number})],l.prototype,"hideDelay",void 0),l=n([D("esp-popover")],l);export{l as EspalierPopover};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getEspBus as c}from"./bus-events.js";function
|
|
1
|
+
import{getEspBus as c}from"./bus-events.js";function l(r){const s=[],t=new Set;let e=r;for(;e&&!t.has(e);){t.add(e);const i=e["linked-popover"];if(i){e=i;continue}const o=e.closest("esp-popover");if(o){s.includes(o)||s.push(o),e=o.parentElement||o.getRootNode()?.host;continue}const n=e.getRootNode();e=n instanceof ShadowRoot?n.host:void 0}return s}class u{constructor(s){this.bus=c(),this.rafId=0,this.positionResizeObserver=null,this.handleClosePopovers=t=>{if(!this.opts.isOpen())return;const e=this.opts.host;if(this.opts.closeStrategy==="source-identity"){if(!t.source||t.source===e||t.source instanceof Node&&(e.contains(t.source)||e.shadowRoot?.contains(t.source)))return}else if(t.skipPopovers?.includes(e))return;this.opts.onShouldClose()},this.onScrollOrResize=()=>{this.rafId||(this.rafId=requestAnimationFrame(()=>{if(this.rafId=0,!!this.opts.isOpen()){if(this.opts.shouldContinueTracking&&!this.opts.shouldContinueTracking()){this.opts.onShouldClose();return}this.opts.onPositionUpdate?.()}}))},this.onDocumentClick=t=>{const e=this.opts.host,i=t.composedPath();if(i.includes(e))return;const o=this.opts.getInsideElements?.()??[];for(const n of o)if(n&&i.includes(n))return;this.opts.isOpen()&&this.opts.onOutsideClick?.()},this.opts=s,s.host.addController(this)}hostConnected(){this.bus.subscribe("close-popovers",this.handleClosePopovers)}hostDisconnected(){this.bus.unsubscribe("close-popovers",this.handleClosePopovers),this.stopTracking(),this.stopOutsideClick()}startTracking(){if(this.opts.onPositionUpdate&&(window.addEventListener("scroll",this.onScrollOrResize,{capture:!0,passive:!0}),window.addEventListener("resize",this.onScrollOrResize,{passive:!0}),this.opts.getPositionElements&&typeof ResizeObserver<"u")){this.positionResizeObserver?.disconnect(),this.positionResizeObserver=new ResizeObserver(this.onScrollOrResize);const s=new Set(this.opts.getPositionElements().filter(Boolean));for(const t of s)this.positionResizeObserver.observe(t)}}stopTracking(){window.removeEventListener("scroll",this.onScrollOrResize,{capture:!0}),window.removeEventListener("resize",this.onScrollOrResize),this.positionResizeObserver?.disconnect(),this.positionResizeObserver=null,this.rafId&&(cancelAnimationFrame(this.rafId),this.rafId=0)}startOutsideClick(){this.opts.onOutsideClick&&document.addEventListener("click",this.onDocumentClick,!0)}stopOutsideClick(){document.removeEventListener("click",this.onDocumentClick,!0)}publishCloseOthers(s=[]){this.bus.publish("close-popovers",{source:this.opts.host,...s.length>0?{skipPopovers:s}:{}})}publishCloseExcept(s){this.bus.publish("close-popovers",{source:this.opts.host,skipPopovers:s})}}export{u as PopoverController,l as findContainingPopovers};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taprootio/espalier",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.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",
|