@taprootio/espalier 2.8.1 → 2.9.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/custom-elements.json +18525 -16609
- package/dist/button/esp-button.d.ts +3 -0
- package/dist/button/esp-button.js +14 -13
- package/dist/flyout/esp-flyout.d.ts +40 -18
- package/dist/flyout/esp-flyout.js +65 -17
- package/dist/form-item/esp-form-item.d.ts +22 -0
- package/dist/form-item/esp-form-item.js +60 -14
- package/dist/help/esp-help-button.d.ts +61 -0
- package/dist/help/esp-help-button.js +49 -0
- package/dist/help/esp-help-provider.d.ts +40 -0
- package/dist/help/esp-help-provider.js +5 -0
- package/dist/help/help-document.js +52 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -1
- package/dist/shared/bus-events.d.ts +20 -1
- package/dist/shared/esp-bus.d.ts +1 -1
- package/dist/shared/esp-bus.js +1 -1
- package/dist/shared/events.d.ts +1 -0
- package/dist/shared/flyout-events.d.ts +16 -5
- package/dist/shared/flyout-events.js +1 -1
- package/dist/shared/help-events.d.ts +55 -0
- package/dist/shared/help-events.js +1 -0
- package/package.json +9 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
var i=function(s,e,t,l){var a=arguments.length,o=a<3?e:l===null?l=Object.getOwnPropertyDescriptor(e,t):l,c;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")o=Reflect.decorate(s,e,t,l);else for(var p=s.length-1;p>=0;p--)(c=s[p])&&(o=(a<3?c(o):a>3?c(e,t,o):c(e,t))||o);return a>3&&o&&Object.defineProperty(e,t,o),o};import{css as d,html as b,nothing as f}from"lit";import{customElement as g,property as n}from"lit/decorators.js";import{EspalierElementBase as u}from"../shared/esp-element-base.js";import{getEspBus as h}from"../shared/bus-events.js";import{requestHelp as m}from"../shared/help-events.js";import{getIconHrefForHost as v}from"../shared/intent-values.js";import{renderSpriteIcon as y}from"../shared/svgs/render-sprite-icon.js";import{resolveHelpTarget as T}from"./help-document.js";let r=class extends u{constructor(){super(...arguments),this.helpUrl="",this.anchor="",this.label="Help",this.helpTitle="",this.active=!1,this.boundHelpStateChanged=e=>{const t=this.resolvedTarget;this.active=!!(e.open&&t&&t.src===e.src&&(t.anchor??"")===(e.anchor??""))},this.handleActivation=()=>{if(this.active){const t=this.resolvedTarget;if(!t)return;h().publish("close-help",{src:t.src,...t.anchor?{anchor:t.anchor}:{}});return}const e=this.resolvedTarget;e&&m({src:e.src,...e.anchor?{anchor:e.anchor}:{},...this.helpTitle.trim()?{title:this.helpTitle.trim()}:{},...this.placementTarget?{placementTarget:this.placementTarget}:{},trigger:this})}}get resolvedTarget(){return T(this,{helpUrl:this.helpUrl,anchor:this.anchor})}connectedCallback(){super.connectedCallback(),h().subscribe("help-state-changed",this.boundHelpStateChanged)}disconnectedCallback(){h().unsubscribe("help-state-changed",this.boundHelpStateChanged),super.disconnectedCallback()}focus(e){this.shadowRoot?.querySelector("button")?.focus(e)}updated(e){super.updated(e),(e.has("helpUrl")||e.has("anchor"))&&(this.active=!1)}render(){if(!this.resolvedTarget)return f;const t=this.getAttribute("aria-label")?.trim()||this.label||"Help",l=v("info",this);return b`
|
|
2
|
+
<button
|
|
3
|
+
type="button"
|
|
4
|
+
aria-label=${t}
|
|
5
|
+
aria-pressed=${this.active?"true":"false"}
|
|
6
|
+
@click=${this.handleActivation}
|
|
7
|
+
>
|
|
8
|
+
${y(l)}
|
|
9
|
+
</button>
|
|
10
|
+
`}};r.styles=[...u.styles,d`
|
|
11
|
+
:host {
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
vertical-align: middle;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
button {
|
|
17
|
+
appearance: none;
|
|
18
|
+
background: transparent;
|
|
19
|
+
border: 0;
|
|
20
|
+
border-radius: 0;
|
|
21
|
+
color: var(--esp-color-link);
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
display: inline-grid;
|
|
24
|
+
font: inherit;
|
|
25
|
+
line-height: 1;
|
|
26
|
+
margin: 0;
|
|
27
|
+
padding: 0;
|
|
28
|
+
place-items: center;
|
|
29
|
+
transition:
|
|
30
|
+
background-color 0.15s ease,
|
|
31
|
+
color 0.15s ease;
|
|
32
|
+
|
|
33
|
+
.generated-icon {
|
|
34
|
+
block-size: 1em;
|
|
35
|
+
inline-size: 1em;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&:hover,
|
|
39
|
+
&[aria-pressed="true"] {
|
|
40
|
+
background: var(--esp-color-link-hover-bg);
|
|
41
|
+
color: var(--esp-color-link-hover);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
&:focus-visible {
|
|
45
|
+
outline: 2px solid var(--esp-color-link);
|
|
46
|
+
outline-offset: 2px;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
`],i([n({attribute:"help-url",type:String})],r.prototype,"helpUrl",void 0),i([n({type:String})],r.prototype,"anchor",void 0),i([n({type:String})],r.prototype,"label",void 0),i([n({attribute:"title",type:String})],r.prototype,"helpTitle",void 0),i([n({attribute:!1})],r.prototype,"placementTarget",void 0),i([n({type:Boolean,reflect:!0})],r.prototype,"active",void 0),r=i([g("esp-help-button")],r);export{r as EspalierHelpButton};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { EspalierElementBase } from "../shared/esp-element-base.js";
|
|
2
|
+
/**
|
|
3
|
+
* Headless provider for URL-addressable help documents. Place one provider
|
|
4
|
+
* inside the same `<esp-root>` as the page's shared `<esp-flyout>`. It
|
|
5
|
+
* services `requestHelp()` calls, fetches and normalizes the document, and
|
|
6
|
+
* swaps an internal help view into the generic flyout surface.
|
|
7
|
+
*
|
|
8
|
+
* Successful documents are cached by absolute source URL. A newer request
|
|
9
|
+
* aborts an older in-flight fetch, so help always reflects the most recent
|
|
10
|
+
* trigger. If no flyout services the provider's presentation request, the
|
|
11
|
+
* original URL opens in a new tab. Fetch failures stay in the flyout and
|
|
12
|
+
* offer an explicit "Open help document" action.
|
|
13
|
+
*
|
|
14
|
+
* ```html
|
|
15
|
+
* <esp-root>
|
|
16
|
+
* <esp-help-provider></esp-help-provider>
|
|
17
|
+
* <esp-page help-src="/help/account.html">
|
|
18
|
+
* <esp-flyout slot="flyout"></esp-flyout>
|
|
19
|
+
* <!-- page content -->
|
|
20
|
+
* </esp-page>
|
|
21
|
+
* </esp-root>
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @docPageTitle Help Provider
|
|
25
|
+
* @docUrl /components/help/provider
|
|
26
|
+
* @menuGroup Feedback
|
|
27
|
+
* @menuLabel Help Provider
|
|
28
|
+
* @menuIcon info
|
|
29
|
+
*/
|
|
30
|
+
export declare class EspalierHelpProvider extends EspalierElementBase {
|
|
31
|
+
connectedCallback(): void;
|
|
32
|
+
disconnectedCallback(): void;
|
|
33
|
+
protected render(): symbol;
|
|
34
|
+
static styles: import("lit").CSSResult[];
|
|
35
|
+
}
|
|
36
|
+
declare global {
|
|
37
|
+
interface HTMLElementTagNameMap {
|
|
38
|
+
"esp-help-provider": EspalierHelpProvider;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
var d=function(r,e,t,n){var o=arguments.length,s=o<3?e:n===null?n=Object.getOwnPropertyDescriptor(e,t):n,i;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(r,e,t,n);else for(var a=r.length-1;a>=0;a--)(i=r[a])&&(s=(o<3?i(s):o>3?i(e,t,s):i(e,t))||s);return o>3&&s&&Object.defineProperty(e,t,s),s};import{css as p,nothing as b}from"lit";import{customElement as f}from"lit/decorators.js";import{EspalierElementBase as v}from"../shared/esp-element-base.js";import{getEspBus as c}from"../shared/bus-events.js";import{publishFlyoutRequest as m}from"../shared/flyout-events.js";import{openHelpInNewTab as h}from"../shared/help-events.js";import{createHelpDocumentView as C,createHelpStatusView as u,normalizeHelpDocument as R}from"./help-document.js";let l=class extends v{constructor(){super(...arguments),this.cache=new Map,this.warnedMissingAnchors=new Set,this.activeRequest=null,this.activeController=null,this.activeContent=null,this.contentObserver=new MutationObserver(()=>{this.activeContent&&!this.activeContent.isConnected&&this.endActiveRequest()}),this.requestSequence=0,this.subscribed=!1,this.boundRequest=e=>{this.handleRequest(e)},this.boundCloseRequest=e=>{let t;try{t=new URL(e.src,document.baseURI).href}catch{return}if(!this.activeRequest||t!==this.activeRequest.src||(e.anchor??"")!==(this.activeRequest.anchor??""))return;const n=this.activeContent?.parentElement;n?.localName==="esp-flyout"&&n.close("programmatic")},this.boundFlyoutClosed=e=>{const t=e.target;!(t instanceof Element)||!this.activeContent||t.contains(this.activeContent)&&this.endActiveRequest()}}connectedCallback(){super.connectedCallback(),this.subscribed||(c().subscribe("request-help",this.boundRequest),c().subscribe("close-help",this.boundCloseRequest),this.subscribed=!0),document.addEventListener("flyout-closed",this.boundFlyoutClosed)}disconnectedCallback(){this.subscribed&&(c().unsubscribe("request-help",this.boundRequest),c().unsubscribe("close-help",this.boundCloseRequest),this.subscribed=!1),document.removeEventListener("flyout-closed",this.boundFlyoutClosed),this.endActiveRequest(),super.disconnectedCallback()}render(){return b}async handleRequest(e){const t=++this.requestSequence;this.activeController?.abort();const n=new AbortController;if(this.activeController=n,this.activeRequest=e,this.publishState(e,!0),this.showInFlyout(e,{heading:e.title??"Help",content:u({message:"Loading help\u2026"})})===0){this.endActiveRequest(),h(e);return}try{const s=this.cache.get(e.src)??await this.fetchDocument(e,n);if(t!==this.requestSequence||n.signal.aborted)return;if(!this.activeContent?.isConnected){this.endActiveRequest();return}this.cache.set(e.src,s);const i=C(s,e.anchor);this.warnForMissingAnchor(e,i.anchorFound),this.showInFlyout(e,{heading:e.title??i.topicTitle??s.title??"Help",content:i.element,fullHeight:i.fullDocument})}catch(s){if(t!==this.requestSequence||n.signal.aborted||w(s))return;if(!this.activeContent?.isConnected){this.endActiveRequest();return}this.showInFlyout(e,{heading:e.title??"Help unavailable",content:u({message:"Help could not be loaded.",actionLabel:"Open help document",onAction:()=>h(e)})})}finally{t===this.requestSequence&&(this.activeController=null)}}async fetchDocument(e,t){const n=await fetch(e.src,{signal:t.signal});if(!n.ok)throw new Error(`Help request failed with HTTP ${n.status}.`);return R(await n.text(),n.url||e.src)}showInFlyout(e,t){this.contentObserver.disconnect(),this.activeContent=t.content instanceof HTMLElement?t.content:null;const n=m({...t,anchor:e.placementTarget??e.trigger,returnFocusTo:e.trigger}),o=this.activeContent?.parentElement;return n&&o&&this.contentObserver.observe(o,{childList:!0}),n?1:0}publishState(e,t){c().publish("help-state-changed",{src:e.src,...e.anchor?{anchor:e.anchor}:{},open:t})}publishClosedState(){this.activeRequest&&(this.publishState(this.activeRequest,!1),this.activeRequest=null)}endActiveRequest(){(this.activeRequest||this.activeController)&&++this.requestSequence,this.activeController?.abort(),this.activeController=null,this.contentObserver.disconnect(),this.activeContent=null,this.publishClosedState()}warnForMissingAnchor(e,t){if(!e.anchor||t)return;const n=`${e.src}#${e.anchor}`;this.warnedMissingAnchors.has(n)||(this.warnedMissingAnchors.add(n),console.warn(`Help anchor "${e.anchor}" was not found in ${e.src}; showing the full document.`))}};l.styles=[p`
|
|
2
|
+
:host {
|
|
3
|
+
display: none;
|
|
4
|
+
}
|
|
5
|
+
`],l=d([f("esp-help-provider")],l);function w(r){return r instanceof DOMException&&r.name==="AbortError"}export{l as EspalierHelpProvider};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import"../button/esp-button.js";import{FLYOUT_FULL_HEIGHT_REQUEST_EVENT as w}from"../shared/flyout-events.js";import{decodeFragment as E}from"../shared/help-events.js";const v=new Set(["A","ABBR","B","BLOCKQUOTE","BR","CODE","DD","DEL","DETAILS","DL","DT","EM","FIGCAPTION","FIGURE","H1","H2","H3","H4","H5","H6","HR","I","IMG","KBD","LI","MARK","OL","P","PRE","Q","S","SAMP","SMALL","STRONG","SUB","SUMMARY","SUP","TABLE","TBODY","TD","TFOOT","TH","THEAD","TR","U","UL","VAR"]),N=new Set(["SCRIPT","STYLE","TEMPLATE","NOSCRIPT"]),y={A:["href"],DETAILS:["open"],IMG:["src","alt","width","height"],LI:["value"],OL:["start","reversed"],TD:["colspan","rowspan"],TH:["colspan","rowspan","scope"]},g=`
|
|
2
|
+
:host {
|
|
3
|
+
color: var(--esp-color-text);
|
|
4
|
+
display: block;
|
|
5
|
+
font-family: var(--esp-font-body);
|
|
6
|
+
font-size: var(--esp-size-font);
|
|
7
|
+
line-height: 1.5;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
[part="content"] {
|
|
11
|
+
overflow-wrap: anywhere;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
[part="content"] > :first-child {
|
|
15
|
+
margin-block-start: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
[part="content"] > :last-child {
|
|
19
|
+
margin-block-end: 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
h1, h2, h3, h4, h5, h6 {
|
|
23
|
+
color: var(--esp-color-headings, var(--esp-color-text));
|
|
24
|
+
font-family: var(--esp-font-headings, var(--esp-font-body));
|
|
25
|
+
line-height: 1.2;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
img {
|
|
29
|
+
block-size: auto;
|
|
30
|
+
max-inline-size: 100%;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
pre {
|
|
34
|
+
max-inline-size: 100%;
|
|
35
|
+
overflow: auto;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
table {
|
|
39
|
+
border-collapse: collapse;
|
|
40
|
+
inline-size: 100%;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
th, td {
|
|
44
|
+
border: 1px solid var(--esp-color-border);
|
|
45
|
+
padding: var(--esp-size-tiny-to-small);
|
|
46
|
+
text-align: start;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
[part="actions"] {
|
|
50
|
+
margin-block-start: var(--esp-size-padding);
|
|
51
|
+
}
|
|
52
|
+
`;function P(e,t={}){const n=t.helpUrl?.trim()??"",o=n?"":H(e),r=n||o;if(!r)return null;let c;try{c=new URL(r,e.ownerDocument.baseURI)}catch{return null}const i=E(c.hash);c.hash="";const a=m(t.anchor,t.fallbackAnchor),s=n?m(i,a):m(a,i),u=new URL(c.href);return s&&(u.hash=s),{src:c.href,...s?{anchor:s}:{},href:u.href}}function k(e,t){const n=new URL(t,document.baseURI);n.hash="";const o=new DOMParser().parseFromString(e,"text/html"),r=o.querySelector("title")?.textContent?.trim()||void 0,c=document.createDocumentFragment();for(const i of[...o.body.childNodes])b(i,c,n.href);return{src:n.href,...r?{title:r}:{},body:c}}function D(e,t){const n=t?.trim()??"";if(!n)return{content:e.body.cloneNode(!0),anchorFound:!0,sectioned:!1};const o=T(e.body,n);if(!o)return{content:e.body.cloneNode(!0),anchorFound:!1,sectioned:!1};const r=A(o);if(!r||!o.parentNode)return{content:e.body.cloneNode(!0),anchorFound:!0,sectioned:!1};const c=document.createDocumentFragment();let i=o.nextSibling;for(;i;){if(i instanceof Element){const a=A(i);if(a&&a<=r)break}c.append(i.cloneNode(!0)),i=i.nextSibling}return{content:c,anchorFound:!0,sectioned:!0,heading:o.textContent?.trim()||void 0}}function B(e,t){const n=t?.trim()||void 0,o=D(e,n),r=document.createElement("section");r.dataset.espHelpDocument="";const c=r.attachShadow({mode:"open"}),i=document.createElement("style");i.textContent=g;const a=document.createElement("div");a.setAttribute("part","content");const s=document.createElement("div");s.setAttribute("part","actions");const u=d=>{a.replaceChildren(e.body.cloneNode(!0)),l?.setAttribute("disabled",""),l?.setAttribute("label","Full document"),r.dispatchEvent(new CustomEvent(w,{bubbles:!0,composed:!0})),d&&queueMicrotask(()=>S(a,d))};let l=null;return o.sectioned?(a.append(o.content),l=document.createElement("esp-button"),l.setAttribute("label","View full document"),l.setAttribute("collapsed",""),l.setAttribute("incognito",""),l.addEventListener("clicked",()=>u(n)),s.append(l)):a.append(o.content),a.addEventListener("click",d=>{const f=d.composedPath().find(L=>L instanceof HTMLAnchorElement)?.getAttribute("href")??"";if(!f)return;if(!f.startsWith("#")){d.preventDefault(),window.open(f,"_blank","noopener,noreferrer");return}d.preventDefault();const p=E(f);p&&(o.sectioned?u(p):S(a,p))}),c.append(i,a,s),{element:r,anchorFound:o.anchorFound,fullDocument:!o.sectioned,...o.heading?{topicTitle:o.heading}:{}}}function M(e){const t=document.createElement("section");t.dataset.espHelpStatus="";const n=t.attachShadow({mode:"open"}),o=document.createElement("style");o.textContent=g;const r=document.createElement("p");if(r.setAttribute("part","message"),r.textContent=e.message,n.append(o,r),e.actionLabel&&e.onAction){const c=document.createElement("div");c.setAttribute("part","actions");const i=document.createElement("esp-button");i.setAttribute("label",e.actionLabel),i.setAttribute("collapsed",""),i.addEventListener("clicked",e.onAction),c.append(i),n.append(c)}return t}function H(e){let t=e;const n=new Set;for(;t&&!n.has(t);){n.add(t);const o=t.getAttribute("help-src")?.trim()??"";if(o)return o;t=h(t)}return""}function h(e){if(e.assignedSlot)return e.assignedSlot;if(e.parentElement)return e.parentElement;const t=e.getRootNode();return t instanceof ShadowRoot?t.host:null}function m(...e){for(const t of e){const n=t?.trim()??"";if(n)return n}}function b(e,t,n){if(e.nodeType===Node.TEXT_NODE){t.appendChild(document.createTextNode(e.textContent??""));return}if(!(e instanceof Element)||N.has(e.tagName))return;if(!v.has(e.tagName)){for(const r of[...e.childNodes])b(r,t,n);return}const o=document.createElement(e.tagName.toLowerCase());R(e,o,n);for(const r of[...e.childNodes])b(r,o,n);t.appendChild(o)}function R(e,t,n){const o=e.getAttribute("id")?.trim();o&&t.setAttribute("id",o);for(const r of y[e.tagName]??[]){if(!e.hasAttribute(r))continue;const c=e.getAttribute(r)??"",i=r==="href"||r==="src"?C(c,n):c;i!==null&&t.setAttribute(r,i)}}function C(e,t){if(!e||e.startsWith("#"))return e;try{const n=new URL(e,t);return["http:","https:","mailto:","tel:"].includes(n.protocol)?n.href:null}catch{return null}}function T(e,t){return[...e.querySelectorAll("[id]")].find(n=>n.id===t)??null}function A(e){const t=/^H([1-6])$/u.exec(e.tagName);return t?Number(t[1]):null}function S(e,t){const n=T(e,t);if(!n)return;const o=x(n);if(!o)return;const r=n.getBoundingClientRect().top,c=o.getBoundingClientRect().top;o.scrollTop+=r-c}function x(e){for(let t=h(e);t;t=h(t)){if(!(t instanceof HTMLElement))continue;const n=getComputedStyle(t).overflowY;if(n==="auto"||n==="scroll")return t}return null}export{B as createHelpDocumentView,M as createHelpStatusView,k as normalizeHelpDocument,P as resolveHelpTarget,D as selectHelpContent};
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ export * from "./color-picker/esp-color-picker.js";
|
|
|
17
17
|
export * from "./flyout/esp-flyout.js";
|
|
18
18
|
export * from "./form/esp-form.js";
|
|
19
19
|
export * from "./form-item/esp-form-item.js";
|
|
20
|
+
export * from "./help/esp-help-button.js";
|
|
21
|
+
export * from "./help/esp-help-provider.js";
|
|
20
22
|
export * from "./header/index.js";
|
|
21
23
|
export * from "./page/esp-page.js";
|
|
22
24
|
export * from "./popover/esp-popover.js";
|
|
@@ -62,7 +64,8 @@ export { FormFieldController, type FormFieldControllerOptions, } from "./shared/
|
|
|
62
64
|
export { traverseToClosest } from "./shared/utilities.js";
|
|
63
65
|
export { showToast, type ToastConfig } from "./shared/toast-events.js";
|
|
64
66
|
export { showFlyout, closeFlyout, type FlyoutConfig, type FlyoutCloseReason, } from "./shared/flyout-events.js";
|
|
65
|
-
export {
|
|
67
|
+
export { requestHelp, type HelpRequest, type HelpState } from "./shared/help-events.js";
|
|
68
|
+
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";
|
|
66
69
|
export * from "./shared/events.js";
|
|
67
70
|
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";
|
|
68
71
|
export { calculatePhotoLayout, type LayoutImage, type PhotoRow, } from "./shared/justified-layout.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"./header/index.js";export*from"./page/esp-page.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
|
|
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"./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 xo,DEFAULT_ICON_VIEW_BOX as ao,INTENT_VARIANTS as lo,normalizeIntentVariant as so,getIconHref as To,getIconHrefForHost as Eo,getIconSpriteUrl as io}from"./shared/intent-values.js";import{EspalierElementBase as Io}from"./shared/esp-element-base.js";import{VALIDITY_CHANGED_EVENT as ho}from"./shared/validation.js";import{FormFieldController as Fo}from"./shared/form-field-controller.js";import{traverseToClosest as uo}from"./shared/utilities.js";import{showToast as Lo}from"./shared/toast-events.js";import{showFlyout as Do,closeFlyout as Ho}from"./shared/flyout-events.js";import{requestHelp as bo}from"./shared/help-events.js";import{getEspBus as Co}from"./shared/bus-events.js";export*from"./shared/events.js";import{getImageDetails as Wo,releasePreviewUrl as Bo}from"./image-upload/image-helpers.js";import{calculatePhotoLayout as vo}from"./shared/justified-layout.js";import{encodeTheme as Go,parseTheme as Oo,mergePartials as Ro,layerThemes as ko,buildTaprootLightTheme as zo,buildTaprootDarkTheme as Yo,NESTED_THEME_KEYS as qo}from"./shared/theme.js";import{WEIGHT_LABELS as Mo,extractWeights as Xo,normalizeWeight as jo,bestAvailableWeight as Jo,extractFamily as Qo,getFallbackFont as Zo}from"./shared/font-helpers.js";import{getGoogleFonts as or}from"./font-picker/esp-font-picker.js";export{xo as DEFAULT_ICON_SPRITE_URL,ao as DEFAULT_ICON_VIEW_BOX,Io as EspalierElementBase,Fo as FormFieldController,lo as INTENT_VARIANTS,qo as NESTED_THEME_KEYS,ho as VALIDITY_CHANGED_EVENT,Mo as WEIGHT_LABELS,Jo as bestAvailableWeight,Yo as buildTaprootDarkTheme,zo as buildTaprootLightTheme,vo as calculatePhotoLayout,Ho as closeFlyout,Go as encodeTheme,Qo as extractFamily,Xo as extractWeights,Co as getEspBus,Zo as getFallbackFont,or as getGoogleFonts,To as getIconHref,Eo as getIconHrefForHost,io as getIconSpriteUrl,Wo as getImageDetails,ko as layerThemes,Ro as mergePartials,so as normalizeIntentVariant,jo as normalizeWeight,Oo as parseTheme,Bo as releasePreviewUrl,bo as requestHelp,Do as showFlyout,Lo as showToast,uo as traverseToClosest};
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
import { EspBus } from "./esp-bus.js";
|
|
30
30
|
import type { ToastConfig } from "./toast-events.js";
|
|
31
31
|
import type { FlyoutConfig } from "./flyout-events.js";
|
|
32
|
+
import type { HelpRequest, HelpState } from "./help-events.js";
|
|
32
33
|
/**
|
|
33
34
|
* Contract for elements that provide a seed color to their subtree.
|
|
34
35
|
* Implemented by `EspalierRoot` (the global provider) and
|
|
@@ -115,6 +116,24 @@ export interface FlyoutEvents {
|
|
|
115
116
|
"show-flyout": FlyoutConfig;
|
|
116
117
|
"close-flyout": Record<string, never>;
|
|
117
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* URL help-system coordination events.
|
|
121
|
+
*
|
|
122
|
+
* `request-help` is published by {@link requestHelp} and serviced by a
|
|
123
|
+
* connected `<esp-help-provider>`. `close-help` asks that provider to close
|
|
124
|
+
* only the flyout presenting the matching topic. The provider publishes
|
|
125
|
+
* `help-state-changed` whenever a topic opens, swaps, or closes so all
|
|
126
|
+
* matching trigger affordances can synchronize `aria-pressed`.
|
|
127
|
+
*
|
|
128
|
+
* @docUrl /api/help-events
|
|
129
|
+
* @menuGroup Bus Events
|
|
130
|
+
* @menuLabel HelpEvents
|
|
131
|
+
*/
|
|
132
|
+
export interface HelpEvents {
|
|
133
|
+
"request-help": HelpRequest;
|
|
134
|
+
"close-help": Pick<HelpRequest, "src" | "anchor">;
|
|
135
|
+
"help-state-changed": HelpState;
|
|
136
|
+
}
|
|
118
137
|
/**
|
|
119
138
|
* Cross-popover coordination events.
|
|
120
139
|
*
|
|
@@ -181,7 +200,7 @@ export interface PageEventMap {
|
|
|
181
200
|
* @menuGroup Bus Events
|
|
182
201
|
* @menuLabel EspBusEventMap
|
|
183
202
|
*/
|
|
184
|
-
export type EspBusEventMap = SchemeEvents & ToastEvents & FlyoutEvents & PopoverEvents & SizeEvents & PageEventMap;
|
|
203
|
+
export type EspBusEventMap = SchemeEvents & ToastEvents & FlyoutEvents & HelpEvents & PopoverEvents & SizeEvents & PageEventMap;
|
|
185
204
|
/**
|
|
186
205
|
* Typed accessor for the singleton bus.
|
|
187
206
|
*
|
package/dist/shared/esp-bus.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export declare class EspBus<TEventMap extends Record<string, any>> {
|
|
|
2
2
|
static getInstance<TBus extends Record<string, any>>(): EspBus<TBus>;
|
|
3
3
|
subscribe<K extends keyof TEventMap>(event: K, callback: (payload: TEventMap[K]) => void): void;
|
|
4
4
|
unsubscribe<K extends keyof TEventMap>(event: K, callback: (payload: TEventMap[K]) => void): void;
|
|
5
|
-
publish<K extends keyof TEventMap>(event: K, payload: TEventMap[K]):
|
|
5
|
+
publish<K extends keyof TEventMap>(event: K, payload: TEventMap[K]): number;
|
|
6
6
|
}
|
package/dist/shared/esp-bus.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class i{constructor(){this.subscribers={}}static getInstance(){return i.instanceBacker||(i.instanceBacker=new i),i.instanceBacker}subscribe(s,r){this.subscribers[s]||(this.subscribers[s]=[]),this.subscribers[s].push(r)}unsubscribe(s,r){this.subscribers[s]&&(this.subscribers[s]=this.subscribers[s].filter(
|
|
1
|
+
class i{constructor(){this.subscribers={}}static getInstance(){return i.instanceBacker||(i.instanceBacker=new i),i.instanceBacker}subscribe(s,r){this.subscribers[s]||(this.subscribers[s]=[]),this.subscribers[s].push(r)}unsubscribe(s,r){this.subscribers[s]&&(this.subscribers[s]=this.subscribers[s].filter(c=>c!==r))}publish(s,r){const c=this.subscribers[s]??[],b=c.length;return c.forEach(t=>t(r)),b}}export{i as EspBus};
|
package/dist/shared/events.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export { type DestroyEspalierInfo } from "../info/esp-info.js";
|
|
|
27
27
|
export { type ValidityChangedDetail, type ValidationError, VALIDITY_CHANGED_EVENT, } from "./validation.js";
|
|
28
28
|
export { type ToastConfig } from "./toast-events.js";
|
|
29
29
|
export { type FlyoutConfig, type FlyoutCloseReason } from "./flyout-events.js";
|
|
30
|
+
export { type HelpRequest, type HelpState } from "./help-events.js";
|
|
30
31
|
export { type PickerItem } from "../pickers/esp-picker-item.js";
|
|
31
32
|
export { type EspalierUploadImage } from "../image-upload/image-helpers.js";
|
|
32
33
|
export { type FontPickerValueChangedDetail, type GoogleFont, type WebSafeFont, } from "../font-picker/esp-font-picker.js";
|
|
@@ -37,14 +37,21 @@ export type FlyoutConfig = {
|
|
|
37
37
|
* has (e.g. declaratively slotted markup).
|
|
38
38
|
*/
|
|
39
39
|
content?: string | Node | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Fill the visible block-size in gutter and docked modes instead of
|
|
42
|
+
* sizing the panel to its content. The content region scrolls
|
|
43
|
+
* independently. Overlay drawers already fill the viewport.
|
|
44
|
+
*/
|
|
45
|
+
fullHeight?: boolean | undefined;
|
|
40
46
|
/**
|
|
41
47
|
* Triggering element whose block-start edge the in-grid flyout
|
|
42
48
|
* should align with. The flyout stays in the page's normal scroll
|
|
43
49
|
* flow, shifting upward only while needed to fit the visible
|
|
44
50
|
* scrollport. Content taller than that scrollport scrolls inside the
|
|
45
51
|
* panel. Overlay drawers ignore this geometry and remain
|
|
46
|
-
* viewport-fixed.
|
|
47
|
-
*
|
|
52
|
+
* viewport-fixed. Its outermost containing `esp-page` also supplies
|
|
53
|
+
* the default flyout scope. When omitted, the flyout starts at the
|
|
54
|
+
* top of the page's content row.
|
|
48
55
|
*/
|
|
49
56
|
anchor?: HTMLElement | undefined;
|
|
50
57
|
/**
|
|
@@ -66,9 +73,13 @@ export type FlyoutConfig = {
|
|
|
66
73
|
* showFlyout({ heading: "Details", content: detailsFragment });
|
|
67
74
|
* ```
|
|
68
75
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
76
|
+
* Anchored requests target the outermost containing `esp-page` by
|
|
77
|
+
* default; a nested flyout with `scope="nearest"` explicitly overrides
|
|
78
|
+
* that routing. The nearest-scope flyout must be a light-DOM descendant
|
|
79
|
+
* of the page whose requests it owns. If no eligible `<esp-flyout>` is
|
|
80
|
+
* connected, the event goes unserviced — callers that need a fallback
|
|
81
|
+
* (e.g. opening a URL in a new tab) should check for a connected flyout
|
|
82
|
+
* themselves.
|
|
72
83
|
*
|
|
73
84
|
* @param config - Flyout configuration.
|
|
74
85
|
* @docUrl /api/show-flyout
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getEspBus as o}from"./bus-events.js";function
|
|
1
|
+
import{getEspBus as o}from"./bus-events.js";const u=new WeakSet,r="flyout-full-height-requested";function n(t={}){s(t)}function s(t={}){const e={...t};return o().publish("show-flyout",e),u.has(e)}function c(t){u.add(t)}function i(){o().publish("close-flyout",{})}export{r as FLYOUT_FULL_HEIGHT_REQUEST_EVENT,i as closeFlyout,c as markFlyoutRequestServiced,s as publishFlyoutRequest,n as showFlyout};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A request for one topic in a URL-addressable help document.
|
|
3
|
+
*
|
|
4
|
+
* @docUrl /api/help-request
|
|
5
|
+
* @menuGroup Configuration
|
|
6
|
+
* @menuLabel HelpRequest
|
|
7
|
+
*/
|
|
8
|
+
export type HelpRequest = {
|
|
9
|
+
/** Absolute document URL without a fragment. */
|
|
10
|
+
src: string;
|
|
11
|
+
/** Stable heading id to show first. */
|
|
12
|
+
anchor?: string | undefined;
|
|
13
|
+
/** Explicit flyout title. */
|
|
14
|
+
title?: string | undefined;
|
|
15
|
+
/** Element whose bounds the contextual flyout should align with. */
|
|
16
|
+
placementTarget?: HTMLElement | undefined;
|
|
17
|
+
/** Originating control used for focus restoration. */
|
|
18
|
+
trigger?: HTMLElement | undefined;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Current help-topic state published by `esp-help-provider`.
|
|
22
|
+
*
|
|
23
|
+
* @docUrl /api/help-state
|
|
24
|
+
* @menuGroup Event Details
|
|
25
|
+
* @menuLabel HelpState
|
|
26
|
+
*/
|
|
27
|
+
export type HelpState = {
|
|
28
|
+
src: string;
|
|
29
|
+
anchor?: string | undefined;
|
|
30
|
+
open: boolean;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Request help through the shared provider. Relative `src` values are
|
|
34
|
+
* resolved against the current document; a fragment becomes `anchor`
|
|
35
|
+
* unless the explicit property wins. When no provider is connected,
|
|
36
|
+
* the resolved topic opens in a new tab.
|
|
37
|
+
*
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { requestHelp } from "@taprootio/espalier";
|
|
40
|
+
*
|
|
41
|
+
* requestHelp({
|
|
42
|
+
* src: "/help/account.html",
|
|
43
|
+
* anchor: "display-name",
|
|
44
|
+
* title: "Account help",
|
|
45
|
+
* placementTarget: document.querySelector<HTMLElement>("#display-name") ?? undefined,
|
|
46
|
+
* trigger: document.querySelector("#account-help") ?? undefined,
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @param config - Help document, topic, title, and optional placement/focus targets.
|
|
51
|
+
* @docUrl /api/request-help
|
|
52
|
+
* @menuGroup Functions
|
|
53
|
+
* @menuLabel requestHelp
|
|
54
|
+
*/
|
|
55
|
+
export declare function requestHelp(config: HelpRequest): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getEspBus as c}from"./bus-events.js";function i(e){const r=u(e);c().publish("request-help",r)===0&&s(r)}function s(e){const r=a(e);window.open(r.href,"_blank","noopener,noreferrer")}function u(e){const r=new URL(e.src,document.baseURI),t=l(r.hash);r.hash="";const n=e.anchor?.trim()||t,o=e.title?.trim()||void 0;return{src:r.href,...n?{anchor:n}:{},...o?{title:o}:{},...e.placementTarget?{placementTarget:e.placementTarget}:{},...e.trigger?{trigger:e.trigger}:{}}}function a(e){const r=new URL(e.src,document.baseURI);return e.anchor&&(r.hash=e.anchor),r}function l(e){const r=e.replace(/^#/,"").trim();if(r)try{return decodeURIComponent(r)}catch{return r}}export{l as decodeFragment,s as openHelpInNewTab,i as requestHelp};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taprootio/espalier",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.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",
|
|
@@ -130,6 +130,14 @@
|
|
|
130
130
|
"types": "./dist/header/index.d.ts",
|
|
131
131
|
"import": "./dist/header/index.js"
|
|
132
132
|
},
|
|
133
|
+
"./help/button": {
|
|
134
|
+
"types": "./dist/help/esp-help-button.d.ts",
|
|
135
|
+
"import": "./dist/help/esp-help-button.js"
|
|
136
|
+
},
|
|
137
|
+
"./help/provider": {
|
|
138
|
+
"types": "./dist/help/esp-help-provider.d.ts",
|
|
139
|
+
"import": "./dist/help/esp-help-provider.js"
|
|
140
|
+
},
|
|
133
141
|
"./image": {
|
|
134
142
|
"types": "./dist/image/esp-image.d.ts",
|
|
135
143
|
"import": "./dist/image/esp-image.js"
|