@justeattakeaway/pie-button
Advanced tools
Comparing version 0.31.0 to 0.32.0
@@ -11,3 +11,3 @@ import type { CSSResult } from 'lit'; | ||
/** | ||
* What type attribute should be applied to the button. For example submit, button or menu. | ||
* What type attribute should be applied to the button. For example submit, button. | ||
*/ | ||
@@ -35,4 +35,48 @@ type: typeof types[number]; | ||
isLoading: boolean; | ||
/** | ||
* The name of the button, submitted as a pair with the button's value as part of the form data, when that button is used to submit the form. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
name?: string; | ||
/** | ||
* Defines the value associated with the button's name when it's submitted with the form data. This value is passed to the server in params when the form is submitted using this button. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
value?: string; | ||
/** | ||
* The URL that processes the information submitted by the button. Overrides the action attribute of the button's form owner. Does nothing if there is no form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formaction?: string; | ||
/** | ||
* If the button is a submit button (it's inside/associated with a <form> and doesn't have type="button"), specifies how to encode the form data that is submitted. | ||
* If this attribute is specified, it overrides the enctype attribute of the button's form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formenctype?: typeof formEncodingtypes[number]; | ||
/** | ||
* If the button is a submit button (it's inside/associated with a <form> and doesn't have type="button"), this attribute specifies the HTTP method used to submit the form. | ||
* If specified, this attribute overrides the method attribute of the button's form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formmethod?: typeof formMethodTypes[number]; | ||
/** | ||
* If the button is a submit button, this Boolean attribute specifies that the form is not to be validated when it is submitted. | ||
* If this attribute is specified, it overrides the novalidate attribute of the button's form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formnovalidate?: boolean; | ||
/** | ||
* If the button is a submit button, this attribute is an author-defined name or standardized, underscore-prefixed keyword indicating where to display the response from submitting the form. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formtarget?: typeof formTargetTypes[number]; | ||
} | ||
export declare const formEncodingtypes: readonly ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]; | ||
export declare const formMethodTypes: readonly ["post", "get", "dialog"]; | ||
export declare const formTargetTypes: readonly ["_self", "_blank", "_parent", "_top"]; | ||
export declare const iconPlacements: readonly ["leading", "trailing"]; | ||
@@ -45,2 +89,6 @@ | ||
export declare class PieButton extends LitElement implements ButtonProps { | ||
static formAssociated: boolean; | ||
private readonly _internals; | ||
get form(): HTMLFormElement | null; | ||
constructor(); | ||
size: ButtonProps['size']; | ||
@@ -53,2 +101,19 @@ type: ButtonProps['type']; | ||
isFullWidth: boolean; | ||
name?: string; | ||
value?: string; | ||
formaction: ButtonProps['formaction']; | ||
formenctype: ButtonProps['formenctype']; | ||
formmethod: ButtonProps['formmethod']; | ||
formnovalidate: ButtonProps['formnovalidate']; | ||
formtarget: ButtonProps['formtarget']; | ||
/** | ||
* This method creates an invisible button of the same type as pie-button. It is then clicked, and immediately removed from the DOM. | ||
* This is done so that we trigger native form actions, such as submit and reset in the browser. The performance impact of adding and removing a single button to the DOM | ||
* should be neglible, however this should be monitored. | ||
* This is the only viable way of guaranteeing native button behaviour when using a web component in place of an actual HTML button. | ||
* | ||
* TODO: if we need to repeat this logic elsewhere, then we should consider moving this code to a shared class or mixin. | ||
*/ | ||
private _simulateNativeButtonClick; | ||
private _handleClick; | ||
render(): TemplateResult<1>; | ||
@@ -61,3 +126,3 @@ focus(): void; | ||
export declare const types: readonly ["submit", "button", "reset", "menu"]; | ||
export declare const types: readonly ["submit", "button", "reset"]; | ||
@@ -64,0 +129,0 @@ export declare type Variant = typeof variants[number]; |
@@ -1,20 +0,19 @@ | ||
import { unsafeCSS as g, LitElement as f, html as p, nothing as h } from "lit"; | ||
import { property as c } from "lit/decorators.js"; | ||
const b = (v, r, t) => function(o, e) { | ||
const i = `#${e}`; | ||
Object.defineProperty(o, e, { | ||
import { unsafeCSS as wt, LitElement as Et, html as R, nothing as ot } from "lit"; | ||
import { property as f } from "lit/decorators.js"; | ||
const N = (v, c, a) => function(m, y) { | ||
const b = `#${y}`; | ||
Object.defineProperty(m, y, { | ||
get() { | ||
return this[i]; | ||
return this[b]; | ||
}, | ||
set(l) { | ||
const m = this[i]; | ||
r.includes(l) ? this[i] = l : (console.error( | ||
`<${v}> Invalid value "${l}" provided for property "${e}".`, | ||
`Must be one of: ${r.join(" | ")}.`, | ||
`Falling back to default value: "${t}"` | ||
), this[i] = t), this.requestUpdate(e, m); | ||
set(h) { | ||
const A = this[b]; | ||
c.includes(h) ? this[b] = h : (console.error( | ||
`<${v}> Invalid value "${h}" provided for property "${y}".`, | ||
`Must be one of: ${c.join(" | ")}.`, | ||
`Falling back to default value: "${a}"` | ||
), this[b] = a), this.requestUpdate(y, A); | ||
} | ||
}); | ||
}, u = `*,*:before,*:after{box-sizing:border-box}@keyframes rotate360{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.o-btn{--btn-border-radius: var(--dt-radius-rounded-e);--btn-font-family: var(--dt-font-interactive-m-family);--btn-font-weight: var(--dt-font-interactive-m-weight);--btn-padding: 10px var(--dt-spacing-e);--btn-font-size: calc(var(--dt-font-size-20) * 1px);--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);--btn-bg-color: var(--dt-color-interactive-brand);--btn-text-color: var(--dt-color-content-interactive-primary);--btn-icon-size: 24px;--spinner-size-s: 20px;--spinner-size-m: 24px;--spinner-border-width-s: 2.5px;--spinner-border-width-m: 3px;--spinner-size: var(--spinner-size-m);--spinner-border-width: var(--spinner-border-width-m);--spinner-base-color-h: var(--dt-color-content-interactive-primary-h);--spinner-base-color-s: var(--dt-color-content-interactive-primary-s);--spinner-base-color-l: var(--dt-color-content-interactive-primary-l);--spinner-left-color-opacity: .35;--spinner-left-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), var(--spinner-left-color-opacity));--spinner-right-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), 1);--spinner-animation-duration: 1.15s;--spinner-animation-timing-function: linear;--spinner-animation-iteration-count: infinite;position:relative;display:flex;gap:var(--dt-spacing-b);align-items:center;justify-content:center;box-sizing:border-box;padding:var(--btn-padding);border:none;border-radius:var(--btn-border-radius);outline:none;background-color:var(--btn-bg-color);font-family:var(--btn-font-family);font-size:var(--btn-font-size);font-weight:var(--btn-font-weight);color:var(--btn-text-color);line-height:var(--btn-line-height);cursor:pointer;user-select:none;inline-size:var(--btn-inline-size)}.o-btn[variant=primary]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) + var(--hover-modifier)))}.o-btn[variant=primary]:active:not(:disabled),.o-btn[variant=primary][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) + var(--active-modifier)))}.o-btn[variant=primary][size=xsmall],.o-btn[variant=primary][size=small-productive]{--btn-bg-color: var(--dt-color-interactive-primary)}.o-btn[variant=primary][size=xsmall]:hover:not(:disabled),.o-btn[variant=primary][size=small-productive]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-primary-h), var(--dt-color-interactive-primary-s), calc(var(--dt-color-interactive-primary-l) + var(--hover-modifier)))}.o-btn[variant=primary][size=xsmall]:active:not(:disabled),.o-btn[variant=primary][size=xsmall][isLoading]:not(:disabled),.o-btn[variant=primary][size=small-productive]:active:not(:disabled),.o-btn[variant=primary][size=small-productive][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-primary-h), var(--dt-color-interactive-primary-s), calc(var(--dt-color-interactive-primary-l) + var(--active-modifier)))}.o-btn[variant=secondary]{--btn-bg-color: var(--dt-color-interactive-secondary);--btn-text-color: var(--dt-color-content-interactive-secondary);--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l)}.o-btn[variant=secondary]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-secondary-h), var(--dt-color-interactive-secondary-s), calc(var(--dt-color-interactive-secondary-l) + var(--hover-modifier)))}.o-btn[variant=secondary]:active:not(:disabled),.o-btn[variant=secondary][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-secondary-h), var(--dt-color-interactive-secondary-s), calc(var(--dt-color-interactive-secondary-l) + var(--active-modifier)))}.o-btn[variant=outline]{--btn-bg-color: transparent;--btn-text-color: var(--dt-color-content-interactive-secondary);border:1px solid var(--dt-color-border-strong);--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l)}.o-btn[variant=outline]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-btn[variant=outline]:active:not(:disabled),.o-btn[variant=outline][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-btn[variant=ghost]{--btn-bg-color: transparent;--btn-text-color: var(--dt-color-content-link);--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l)}.o-btn[variant=ghost]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-btn[variant=ghost]:active:not(:disabled),.o-btn[variant=ghost][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-btn[variant=inverse]{--btn-bg-color: var(--dt-color-interactive-inverse);--btn-text-color: var(--dt-color-content-interactive-secondary);--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l)}.o-btn[variant=inverse]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-inverse-h), var(--dt-color-interactive-inverse-s), calc(var(--dt-color-interactive-inverse-l) + var(--hover-modifier)))}.o-btn[variant=inverse]:active:not(:disabled),.o-btn[variant=inverse][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-inverse-h), var(--dt-color-interactive-inverse-s), calc(var(--dt-color-interactive-inverse-l) + var(--active-modifier)))}.o-btn[variant=ghost-inverse],.o-btn[variant=outline-inverse]{--btn-bg-color: transparent;--btn-text-color: var(--dt-color-content-interactive-primary)}.o-btn[variant=ghost-inverse]:hover:not(:disabled),.o-btn[variant=outline-inverse]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), var(--dt-color-container-default-l), var(--hover-modifier))}.o-btn[variant=ghost-inverse]:active:not(:disabled),.o-btn[variant=ghost-inverse][isLoading]:not(:disabled),.o-btn[variant=outline-inverse]:active:not(:disabled),.o-btn[variant=outline-inverse][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), var(--dt-color-container-default-l), var(--active-modifier))}.o-btn[variant=outline-inverse]{border:1px solid var(--dt-color-border-strong)}.o-btn[variant=destructive]{--btn-bg-color: var(--dt-color-support-error)}.o-btn[variant=destructive]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-support-error-h), var(--dt-color-support-error-s), calc(var(--dt-color-support-error-l) + var(--hover-modifier)))}.o-btn[variant=destructive]:active:not(:disabled),.o-btn[variant=destructive][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-support-error-h), var(--dt-color-support-error-s), calc(var(--dt-color-support-error-l) + var(--active-modifier)))}.o-btn[variant=destructive-ghost]{--btn-bg-color: transparent;--btn-text-color: var(--dt-color-content-interactive-error);--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l)}.o-btn[variant=destructive-ghost]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-btn[variant=destructive-ghost]:active:not(:disabled),.o-btn[variant=destructive-ghost][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-btn[isFullWidth]{--btn-inline-size: 100%}.o-btn[disabled]{--btn-text-color: var(--dt-color-content-disabled) !important;cursor:not-allowed}.o-btn[disabled]:not([variant=ghost],[variant=ghost-inverse],[variant=destructive-ghost]){--btn-bg-color: var(--dt-color-disabled-01) !important}.o-btn[disabled][variant=outline]{border-color:var(--dt-color-disabled-01)!important}.o-btn[size=xsmall]{--btn-padding: 6px var(--dt-spacing-b);--btn-font-size: calc(var(--dt-font-size-14) * 1px);--btn-line-height: calc(var(--dt-font-size-14-line-height) * 1px);--btn-icon-size: 16px;--spinner-size: var(--spinner-size-s);--spinner-border-width: var(--spinner-border-width-s)}.o-btn[size=small-expressive]{--btn-padding: 6px var(--dt-spacing-d);--btn-font-size: calc(var(--dt-font-size-20) * 1px);--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);--btn-icon-size: 20px;--spinner-size: var(--spinner-size-s);--spinner-border-width: var(--spinner-border-width-s)}.o-btn[size=small-productive]{--btn-padding: 8px var(--dt-spacing-d);--btn-font-size: calc(var(--dt-font-size-16) * 1px);--btn-line-height: calc(var(--dt-font-size-16-line-height) * 1px);--btn-icon-size: 20px;--spinner-size: var(--spinner-size-s);--spinner-border-width: var(--spinner-border-width-s)}.o-btn[size=large]{--btn-padding: 14px var(--dt-spacing-e);--btn-font-size: calc(var(--dt-font-size-20) * 1px);--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);--spinner-size: var(--spinner-size-m);--spinner-border-width: var(--spinner-border-width-m)}.o-btn[isLoading]:before{content:"";position:absolute;left:50%;top:50%;translate:-50% -50%;height:var(--spinner-size);width:var(--spinner-size);display:block;background-color:transparent;border-radius:50%;border-color:var(--spinner-left-color) var(--spinner-right-color) var(--spinner-right-color) var(--spinner-left-color);border-width:var(--spinner-border-width);border-style:solid;will-change:transform;animation:rotate360 var(--spinner-animation-duration) var(--spinner-animation-timing-function) var(--spinner-animation-iteration-count)}.o-btn[isLoading]>*{visibility:hidden}.o-btn:focus-visible{box-shadow:0 0 0 2px var(--dt-color-focus-inner),0 0 0 4px var(--dt-color-focus-outer);outline:none}::slotted(svg){height:var(--btn-icon-size);width:var(--btn-icon-size)} | ||
`, y = ["xsmall", "small-productive", "small-expressive", "medium", "large"], z = ["submit", "button", "reset", "menu"], x = [ | ||
}, xt = ["xsmall", "small-productive", "small-expressive", "medium", "large"], Mt = ["submit", "button", "reset"], kt = [ | ||
"primary", | ||
@@ -29,75 +28,597 @@ "secondary", | ||
"destructive-ghost" | ||
], w = ["leading", "trailing"]; | ||
var k = Object.defineProperty, L = Object.getOwnPropertyDescriptor, s = (v, r, t, a) => { | ||
for (var o = a > 1 ? void 0 : a ? L(r, t) : r, e = v.length - 1, i; e >= 0; e--) | ||
(i = v[e]) && (o = (a ? i(r, t, o) : i(o)) || o); | ||
return a && o && k(r, t, o), o; | ||
], zt = ["leading", "trailing"], Tt = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"], St = ["post", "get", "dialog"], Vt = ["_self", "_blank", "_parent", "_top"], At = `*,*:before,*:after{box-sizing:border-box}@keyframes rotate360{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.o-btn{--btn-border-radius: var(--dt-radius-rounded-e);--btn-font-family: var(--dt-font-interactive-m-family);--btn-font-weight: var(--dt-font-interactive-m-weight);--btn-padding: 10px var(--dt-spacing-e);--btn-font-size: calc(var(--dt-font-size-20) * 1px);--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);--btn-bg-color: var(--dt-color-interactive-brand);--btn-text-color: var(--dt-color-content-interactive-primary);--btn-icon-size: 24px;--spinner-size-s: 20px;--spinner-size-m: 24px;--spinner-border-width-s: 2.5px;--spinner-border-width-m: 3px;--spinner-size: var(--spinner-size-m);--spinner-border-width: var(--spinner-border-width-m);--spinner-base-color-h: var(--dt-color-content-interactive-primary-h);--spinner-base-color-s: var(--dt-color-content-interactive-primary-s);--spinner-base-color-l: var(--dt-color-content-interactive-primary-l);--spinner-left-color-opacity: .35;--spinner-left-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), var(--spinner-left-color-opacity));--spinner-right-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), 1);--spinner-animation-duration: 1.15s;--spinner-animation-timing-function: linear;--spinner-animation-iteration-count: infinite;position:relative;display:flex;gap:var(--dt-spacing-b);align-items:center;justify-content:center;box-sizing:border-box;padding:var(--btn-padding);border:none;border-radius:var(--btn-border-radius);outline:none;background-color:var(--btn-bg-color);font-family:var(--btn-font-family);font-size:var(--btn-font-size);font-weight:var(--btn-font-weight);color:var(--btn-text-color);line-height:var(--btn-line-height);cursor:pointer;user-select:none;inline-size:var(--btn-inline-size)}.o-btn[variant=primary]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) + var(--hover-modifier)))}.o-btn[variant=primary]:active:not(:disabled),.o-btn[variant=primary][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) + var(--active-modifier)))}.o-btn[variant=primary][size=xsmall],.o-btn[variant=primary][size=small-productive]{--btn-bg-color: var(--dt-color-interactive-primary)}.o-btn[variant=primary][size=xsmall]:hover:not(:disabled),.o-btn[variant=primary][size=small-productive]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-primary-h), var(--dt-color-interactive-primary-s), calc(var(--dt-color-interactive-primary-l) + var(--hover-modifier)))}.o-btn[variant=primary][size=xsmall]:active:not(:disabled),.o-btn[variant=primary][size=xsmall][isLoading]:not(:disabled),.o-btn[variant=primary][size=small-productive]:active:not(:disabled),.o-btn[variant=primary][size=small-productive][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-primary-h), var(--dt-color-interactive-primary-s), calc(var(--dt-color-interactive-primary-l) + var(--active-modifier)))}.o-btn[variant=secondary]{--btn-bg-color: var(--dt-color-interactive-secondary);--btn-text-color: var(--dt-color-content-interactive-secondary);--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l)}.o-btn[variant=secondary]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-secondary-h), var(--dt-color-interactive-secondary-s), calc(var(--dt-color-interactive-secondary-l) + var(--hover-modifier)))}.o-btn[variant=secondary]:active:not(:disabled),.o-btn[variant=secondary][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-secondary-h), var(--dt-color-interactive-secondary-s), calc(var(--dt-color-interactive-secondary-l) + var(--active-modifier)))}.o-btn[variant=outline]{--btn-bg-color: transparent;--btn-text-color: var(--dt-color-content-interactive-secondary);border:1px solid var(--dt-color-border-strong);--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l)}.o-btn[variant=outline]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-btn[variant=outline]:active:not(:disabled),.o-btn[variant=outline][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-btn[variant=ghost]{--btn-bg-color: transparent;--btn-text-color: var(--dt-color-content-link);--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l)}.o-btn[variant=ghost]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-btn[variant=ghost]:active:not(:disabled),.o-btn[variant=ghost][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-btn[variant=inverse]{--btn-bg-color: var(--dt-color-interactive-inverse);--btn-text-color: var(--dt-color-content-interactive-secondary);--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l)}.o-btn[variant=inverse]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-inverse-h), var(--dt-color-interactive-inverse-s), calc(var(--dt-color-interactive-inverse-l) + var(--hover-modifier)))}.o-btn[variant=inverse]:active:not(:disabled),.o-btn[variant=inverse][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-inverse-h), var(--dt-color-interactive-inverse-s), calc(var(--dt-color-interactive-inverse-l) + var(--active-modifier)))}.o-btn[variant=ghost-inverse],.o-btn[variant=outline-inverse]{--btn-bg-color: transparent;--btn-text-color: var(--dt-color-content-interactive-primary)}.o-btn[variant=ghost-inverse]:hover:not(:disabled),.o-btn[variant=outline-inverse]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), var(--dt-color-container-default-l), var(--hover-modifier))}.o-btn[variant=ghost-inverse]:active:not(:disabled),.o-btn[variant=ghost-inverse][isLoading]:not(:disabled),.o-btn[variant=outline-inverse]:active:not(:disabled),.o-btn[variant=outline-inverse][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), var(--dt-color-container-default-l), var(--active-modifier))}.o-btn[variant=outline-inverse]{border:1px solid var(--dt-color-border-strong)}.o-btn[variant=destructive]{--btn-bg-color: var(--dt-color-support-error)}.o-btn[variant=destructive]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-support-error-h), var(--dt-color-support-error-s), calc(var(--dt-color-support-error-l) + var(--hover-modifier)))}.o-btn[variant=destructive]:active:not(:disabled),.o-btn[variant=destructive][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-support-error-h), var(--dt-color-support-error-s), calc(var(--dt-color-support-error-l) + var(--active-modifier)))}.o-btn[variant=destructive-ghost]{--btn-bg-color: transparent;--btn-text-color: var(--dt-color-content-interactive-error);--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l)}.o-btn[variant=destructive-ghost]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-btn[variant=destructive-ghost]:active:not(:disabled),.o-btn[variant=destructive-ghost][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-btn[isFullWidth]{--btn-inline-size: 100%}.o-btn[disabled]{--btn-text-color: var(--dt-color-content-disabled) !important;cursor:not-allowed}.o-btn[disabled]:not([variant=ghost],[variant=ghost-inverse],[variant=destructive-ghost]){--btn-bg-color: var(--dt-color-disabled-01) !important}.o-btn[disabled][variant=outline]{border-color:var(--dt-color-disabled-01)!important}.o-btn[size=xsmall]{--btn-padding: 6px var(--dt-spacing-b);--btn-font-size: calc(var(--dt-font-size-14) * 1px);--btn-line-height: calc(var(--dt-font-size-14-line-height) * 1px);--btn-icon-size: 16px;--spinner-size: var(--spinner-size-s);--spinner-border-width: var(--spinner-border-width-s)}.o-btn[size=small-expressive]{--btn-padding: 6px var(--dt-spacing-d);--btn-font-size: calc(var(--dt-font-size-20) * 1px);--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);--btn-icon-size: 20px;--spinner-size: var(--spinner-size-s);--spinner-border-width: var(--spinner-border-width-s)}.o-btn[size=small-productive]{--btn-padding: 8px var(--dt-spacing-d);--btn-font-size: calc(var(--dt-font-size-16) * 1px);--btn-line-height: calc(var(--dt-font-size-16-line-height) * 1px);--btn-icon-size: 20px;--spinner-size: var(--spinner-size-s);--spinner-border-width: var(--spinner-border-width-s)}.o-btn[size=large]{--btn-padding: 14px var(--dt-spacing-e);--btn-font-size: calc(var(--dt-font-size-20) * 1px);--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);--spinner-size: var(--spinner-size-m);--spinner-border-width: var(--spinner-border-width-m)}.o-btn[isLoading]:before{content:"";position:absolute;left:50%;top:50%;translate:-50% -50%;height:var(--spinner-size);width:var(--spinner-size);display:block;background-color:transparent;border-radius:50%;border-color:var(--spinner-left-color) var(--spinner-right-color) var(--spinner-right-color) var(--spinner-left-color);border-width:var(--spinner-border-width);border-style:solid;will-change:transform;animation:rotate360 var(--spinner-animation-duration) var(--spinner-animation-timing-function) var(--spinner-animation-iteration-count)}.o-btn[isLoading]>*{visibility:hidden}.o-btn:focus-visible{box-shadow:0 0 0 2px var(--dt-color-focus-inner),0 0 0 4px var(--dt-color-focus-outer);outline:none}::slotted(svg){height:var(--btn-icon-size);width:var(--btn-icon-size)} | ||
`; | ||
(function() { | ||
const v = /* @__PURE__ */ new WeakMap(), c = /* @__PURE__ */ new WeakMap(), a = /* @__PURE__ */ new WeakMap(), l = /* @__PURE__ */ new WeakMap(), m = /* @__PURE__ */ new WeakMap(), y = /* @__PURE__ */ new WeakMap(), b = /* @__PURE__ */ new WeakMap(), h = /* @__PURE__ */ new WeakMap(), A = /* @__PURE__ */ new WeakMap(), F = /* @__PURE__ */ new WeakMap(), W = /* @__PURE__ */ new WeakMap(), H = /* @__PURE__ */ new WeakMap(), D = /* @__PURE__ */ new WeakMap(), B = /* @__PURE__ */ new WeakMap(), L = /* @__PURE__ */ new WeakMap(), C = { | ||
ariaAtomic: "aria-atomic", | ||
ariaAutoComplete: "aria-autocomplete", | ||
ariaBusy: "aria-busy", | ||
ariaChecked: "aria-checked", | ||
ariaColCount: "aria-colcount", | ||
ariaColIndex: "aria-colindex", | ||
ariaColIndexText: "aria-colindextext", | ||
ariaColSpan: "aria-colspan", | ||
ariaCurrent: "aria-current", | ||
ariaDisabled: "aria-disabled", | ||
ariaExpanded: "aria-expanded", | ||
ariaHasPopup: "aria-haspopup", | ||
ariaHidden: "aria-hidden", | ||
ariaInvalid: "aria-invalid", | ||
ariaKeyShortcuts: "aria-keyshortcuts", | ||
ariaLabel: "aria-label", | ||
ariaLevel: "aria-level", | ||
ariaLive: "aria-live", | ||
ariaModal: "aria-modal", | ||
ariaMultiLine: "aria-multiline", | ||
ariaMultiSelectable: "aria-multiselectable", | ||
ariaOrientation: "aria-orientation", | ||
ariaPlaceholder: "aria-placeholder", | ||
ariaPosInSet: "aria-posinset", | ||
ariaPressed: "aria-pressed", | ||
ariaReadOnly: "aria-readonly", | ||
ariaRelevant: "aria-relevant", | ||
ariaRequired: "aria-required", | ||
ariaRoleDescription: "aria-roledescription", | ||
ariaRowCount: "aria-rowcount", | ||
ariaRowIndex: "aria-rowindex", | ||
ariaRowIndexText: "aria-rowindextext", | ||
ariaRowSpan: "aria-rowspan", | ||
ariaSelected: "aria-selected", | ||
ariaSetSize: "aria-setsize", | ||
ariaSort: "aria-sort", | ||
ariaValueMax: "aria-valuemax", | ||
ariaValueMin: "aria-valuemin", | ||
ariaValueNow: "aria-valuenow", | ||
ariaValueText: "aria-valuetext", | ||
role: "role" | ||
}, it = (r, t) => { | ||
for (let e in C) { | ||
t[e] = null; | ||
let o = null; | ||
const i = C[e]; | ||
Object.defineProperty(t, e, { | ||
get() { | ||
return o; | ||
}, | ||
set(s) { | ||
o = s, r.isConnected ? r.setAttribute(i, s) : F.set(r, t); | ||
} | ||
}); | ||
} | ||
}; | ||
function q(r) { | ||
const t = l.get(r), { form: e } = t; | ||
Q(r, e, t), J(r, t.labels); | ||
} | ||
const U = (r, t = !1) => { | ||
const e = document.createTreeWalker(r, NodeFilter.SHOW_ELEMENT, { | ||
acceptNode(s) { | ||
return l.has(s) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP; | ||
} | ||
}); | ||
let o = e.nextNode(); | ||
const i = !t || r.disabled; | ||
for (; o; ) | ||
o.formDisabledCallback && i && $(o, r.disabled), o = e.nextNode(); | ||
}, j = { attributes: !0, attributeFilter: ["disabled", "name"] }, M = S() ? new MutationObserver((r) => { | ||
for (const t of r) { | ||
const e = t.target; | ||
if (t.attributeName === "disabled" && (e.constructor.formAssociated ? $(e, e.hasAttribute("disabled")) : e.localName === "fieldset" && U(e)), t.attributeName === "name" && e.constructor.formAssociated) { | ||
const o = l.get(e), i = A.get(e); | ||
o.setFormValue(i); | ||
} | ||
} | ||
}) : {}; | ||
function P(r) { | ||
r.forEach((t) => { | ||
const { addedNodes: e, removedNodes: o } = t, i = Array.from(e), s = Array.from(o); | ||
i.forEach((n) => { | ||
var u; | ||
if (l.has(n) && n.constructor.formAssociated && q(n), F.has(n)) { | ||
const d = F.get(n); | ||
Object.keys(C).filter((w) => d[w] !== null).forEach((w) => { | ||
n.setAttribute(C[w], d[w]); | ||
}), F.delete(n); | ||
} | ||
if (L.has(n)) { | ||
const d = L.get(n); | ||
n.setAttribute("internals-valid", d.validity.valid.toString()), n.setAttribute("internals-invalid", (!d.validity.valid).toString()), n.setAttribute("aria-invalid", (!d.validity.valid).toString()), L.delete(n); | ||
} | ||
if (n.localName === "form") { | ||
const d = h.get(n), x = document.createTreeWalker(n, NodeFilter.SHOW_ELEMENT, { | ||
acceptNode(rt) { | ||
return l.has(rt) && !(d && d.has(rt)) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP; | ||
} | ||
}); | ||
let w = x.nextNode(); | ||
for (; w; ) | ||
q(w), w = x.nextNode(); | ||
} | ||
n.localName === "fieldset" && ((u = M.observe) == null || u.call(M, n, j), U(n, !0)); | ||
}), s.forEach((n) => { | ||
const u = l.get(n); | ||
u && a.get(u) && K(u), b.has(n) && b.get(n).disconnect(); | ||
}); | ||
}); | ||
} | ||
function at(r) { | ||
r.forEach((t) => { | ||
const { removedNodes: e } = t; | ||
e.forEach((o) => { | ||
const i = D.get(t.target); | ||
l.has(o) && Y(o), i.disconnect(); | ||
}); | ||
}); | ||
} | ||
const nt = (r) => { | ||
var e; | ||
const t = new MutationObserver(at); | ||
(e = t.observe) == null || e.call(t, r, { childList: !0 }), D.set(r, t); | ||
}; | ||
S() && new MutationObserver(P); | ||
const _ = { | ||
childList: !0, | ||
subtree: !0 | ||
}, $ = (r, t) => { | ||
r.toggleAttribute("internals-disabled", t), t ? r.setAttribute("aria-disabled", "true") : r.removeAttribute("aria-disabled"), r.formDisabledCallback && r.formDisabledCallback.apply(r, [t]); | ||
}, K = (r) => { | ||
a.get(r).forEach((e) => { | ||
e.remove(); | ||
}), a.set(r, []); | ||
}, G = (r, t) => { | ||
const e = document.createElement("input"); | ||
return e.type = "hidden", e.name = r.getAttribute("name"), r.after(e), a.get(t).push(e), e; | ||
}, st = (r, t) => { | ||
var e; | ||
a.set(t, []), (e = M.observe) == null || e.call(M, r, j); | ||
}, J = (r, t) => { | ||
if (t.length) { | ||
Array.from(t).forEach((o) => o.addEventListener("click", r.click.bind(r))); | ||
let e = t[0].id; | ||
t[0].id || (e = `${t[0].htmlFor}_Label`, t[0].id = e), r.setAttribute("aria-labelledby", e); | ||
} | ||
}, I = (r) => { | ||
const t = Array.from(r.elements).filter((s) => !s.tagName.includes("-") && s.validity).map((s) => s.validity.valid), e = h.get(r) || [], o = Array.from(e).filter((s) => s.isConnected).map((s) => l.get(s).validity.valid), i = [...t, ...o].includes(!1); | ||
r.toggleAttribute("internals-invalid", i), r.toggleAttribute("internals-valid", !i); | ||
}, lt = (r) => { | ||
I(T(r.target)); | ||
}, ct = (r) => { | ||
I(T(r.target)); | ||
}, dt = (r) => { | ||
const t = ["button[type=submit]", "input[type=submit]", "button:not([type])"].map((e) => `${e}:not([disabled])`).map((e) => `${e}:not([form])${r.id ? `,${e}[form='${r.id}']` : ""}`).join(","); | ||
r.addEventListener("click", (e) => { | ||
if (e.target.closest(t)) { | ||
const i = h.get(r); | ||
if (r.noValidate) | ||
return; | ||
i.size && Array.from(i).reverse().map((u) => l.get(u).reportValidity()).includes(!1) && e.preventDefault(); | ||
} | ||
}); | ||
}, vt = (r) => { | ||
const t = h.get(r.target); | ||
t && t.size && t.forEach((e) => { | ||
e.constructor.formAssociated && e.formResetCallback && e.formResetCallback.apply(e); | ||
}); | ||
}, Q = (r, t, e) => { | ||
if (t) { | ||
const o = h.get(t); | ||
if (o) | ||
o.add(r); | ||
else { | ||
const i = /* @__PURE__ */ new Set(); | ||
i.add(r), h.set(t, i), dt(t), t.addEventListener("reset", vt), t.addEventListener("input", lt), t.addEventListener("change", ct); | ||
} | ||
y.set(t, { ref: r, internals: e }), r.constructor.formAssociated && r.formAssociatedCallback && setTimeout(() => { | ||
r.formAssociatedCallback.apply(r, [t]); | ||
}, 0), I(t); | ||
} | ||
}, T = (r) => { | ||
let t = r.parentNode; | ||
return t && t.tagName !== "FORM" && (t = T(t)), t; | ||
}, E = (r, t, e = DOMException) => { | ||
if (!r.constructor.formAssociated) | ||
throw new e(t); | ||
}, X = (r, t, e) => { | ||
const o = h.get(r); | ||
return o && o.size && o.forEach((i) => { | ||
l.get(i)[e]() || (t = !1); | ||
}), t; | ||
}, Y = (r) => { | ||
if (r.constructor.formAssociated) { | ||
const t = l.get(r), { labels: e, form: o } = t; | ||
J(r, e), Q(r, o, t); | ||
} | ||
}; | ||
function S() { | ||
return typeof MutationObserver < "u"; | ||
} | ||
class pt { | ||
constructor() { | ||
this.badInput = !1, this.customError = !1, this.patternMismatch = !1, this.rangeOverflow = !1, this.rangeUnderflow = !1, this.stepMismatch = !1, this.tooLong = !1, this.tooShort = !1, this.typeMismatch = !1, this.valid = !0, this.valueMissing = !1, Object.seal(this); | ||
} | ||
} | ||
const ht = (r) => (r.badInput = !1, r.customError = !1, r.patternMismatch = !1, r.rangeOverflow = !1, r.rangeUnderflow = !1, r.stepMismatch = !1, r.tooLong = !1, r.tooShort = !1, r.typeMismatch = !1, r.valid = !0, r.valueMissing = !1, r), mt = (r, t, e) => (r.valid = bt(t), Object.keys(t).forEach((o) => r[o] = t[o]), e && I(e), r), bt = (r) => { | ||
let t = !0; | ||
for (let e in r) | ||
e !== "valid" && r[e] !== !1 && (t = !1); | ||
return t; | ||
}, O = /* @__PURE__ */ new WeakMap(); | ||
function Z(r, t) { | ||
r.toggleAttribute(t, !0), r.part && r.part.add(t); | ||
} | ||
class V extends Set { | ||
static get isPolyfilled() { | ||
return !0; | ||
} | ||
constructor(t) { | ||
if (super(), !t || !t.tagName || t.tagName.indexOf("-") === -1) | ||
throw new TypeError("Illegal constructor"); | ||
O.set(this, t); | ||
} | ||
add(t) { | ||
if (!/^--/.test(t) || typeof t != "string") | ||
throw new DOMException(`Failed to execute 'add' on 'CustomStateSet': The specified value ${t} must start with '--'.`); | ||
const e = super.add(t), o = O.get(this), i = `state${t}`; | ||
return o.isConnected ? Z(o, i) : setTimeout(() => { | ||
Z(o, i); | ||
}), e; | ||
} | ||
clear() { | ||
for (let [t] of this.entries()) | ||
this.delete(t); | ||
super.clear(); | ||
} | ||
delete(t) { | ||
const e = super.delete(t), o = O.get(this); | ||
return o.isConnected ? (o.toggleAttribute(`state${t}`, !1), o.part && o.part.remove(`state${t}`)) : setTimeout(() => { | ||
o.toggleAttribute(`state${t}`, !1), o.part && o.part.remove(`state${t}`); | ||
}), e; | ||
} | ||
} | ||
function tt(r, t, e, o) { | ||
if (e === "a" && !o) | ||
throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof t == "function" ? r !== t || !o : !t.has(r)) | ||
throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return e === "m" ? o : e === "a" ? o.call(r) : o ? o.value : t.get(r); | ||
} | ||
function ut(r, t, e, o, i) { | ||
if (o === "m") | ||
throw new TypeError("Private method is not writable"); | ||
if (o === "a" && !i) | ||
throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof t == "function" ? r !== t || !i : !t.has(r)) | ||
throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return o === "a" ? i.call(r, e) : i ? i.value = e : t.set(r, e), e; | ||
} | ||
var k; | ||
class ft { | ||
constructor(t) { | ||
k.set(this, void 0), ut(this, k, t, "f"); | ||
for (let e = 0; e < t.length; e++) { | ||
let o = t[e]; | ||
this[e] = o, o.hasAttribute("name") && (this[o.getAttribute("name")] = o); | ||
} | ||
Object.freeze(this); | ||
} | ||
get length() { | ||
return tt(this, k, "f").length; | ||
} | ||
[(k = /* @__PURE__ */ new WeakMap(), Symbol.iterator)]() { | ||
return tt(this, k, "f")[Symbol.iterator](); | ||
} | ||
item(t) { | ||
return this[t] == null ? null : this[t]; | ||
} | ||
namedItem(t) { | ||
return this[t] == null ? null : this[t]; | ||
} | ||
} | ||
function gt() { | ||
const r = HTMLFormElement.prototype.checkValidity; | ||
HTMLFormElement.prototype.checkValidity = e; | ||
const t = HTMLFormElement.prototype.reportValidity; | ||
HTMLFormElement.prototype.reportValidity = o; | ||
function e(...s) { | ||
let n = r.apply(this, s); | ||
return X(this, n, "checkValidity"); | ||
} | ||
function o(...s) { | ||
let n = t.apply(this, s); | ||
return X(this, n, "reportValidity"); | ||
} | ||
const { get: i } = Object.getOwnPropertyDescriptor(HTMLFormElement.prototype, "elements"); | ||
Object.defineProperty(HTMLFormElement.prototype, "elements", { | ||
get(...s) { | ||
const n = i.call(this, ...s), u = Array.from(h.get(this) || []); | ||
if (u.length === 0) | ||
return n; | ||
const d = Array.from(n).concat(u).sort((x, w) => x.compareDocumentPosition ? x.compareDocumentPosition(w) & 2 ? 1 : -1 : 0); | ||
return new ft(d); | ||
} | ||
}); | ||
} | ||
class et { | ||
static get isPolyfilled() { | ||
return !0; | ||
} | ||
constructor(t) { | ||
if (!t || !t.tagName || t.tagName.indexOf("-") === -1) | ||
throw new TypeError("Illegal constructor"); | ||
const e = t.getRootNode(), o = new pt(); | ||
this.states = new V(t), v.set(this, t), c.set(this, o), l.set(t, this), it(t, this), st(t, this), Object.seal(this), e instanceof DocumentFragment && nt(e); | ||
} | ||
checkValidity() { | ||
const t = v.get(this); | ||
if (E(t, "Failed to execute 'checkValidity' on 'ElementInternals': The target element is not a form-associated custom element."), !this.willValidate) | ||
return !0; | ||
const e = c.get(this); | ||
if (!e.valid) { | ||
const o = new Event("invalid", { | ||
bubbles: !1, | ||
cancelable: !0, | ||
composed: !1 | ||
}); | ||
t.dispatchEvent(o); | ||
} | ||
return e.valid; | ||
} | ||
get form() { | ||
const t = v.get(this); | ||
E(t, "Failed to read the 'form' property from 'ElementInternals': The target element is not a form-associated custom element."); | ||
let e; | ||
return t.constructor.formAssociated === !0 && (e = T(t)), e; | ||
} | ||
get labels() { | ||
const t = v.get(this); | ||
E(t, "Failed to read the 'labels' property from 'ElementInternals': The target element is not a form-associated custom element."); | ||
const e = t.getAttribute("id"), o = t.getRootNode(); | ||
return o && e ? o.querySelectorAll(`[for="${e}"]`) : []; | ||
} | ||
reportValidity() { | ||
const t = v.get(this); | ||
if (E(t, "Failed to execute 'reportValidity' on 'ElementInternals': The target element is not a form-associated custom element."), !this.willValidate) | ||
return !0; | ||
const e = this.checkValidity(), o = H.get(this); | ||
if (o && !t.constructor.formAssociated) | ||
throw new DOMException("Failed to execute 'reportValidity' on 'ElementInternals': The target element is not a form-associated custom element."); | ||
return !e && o && (t.focus(), o.focus()), e; | ||
} | ||
setFormValue(t) { | ||
const e = v.get(this); | ||
if (E(e, "Failed to execute 'setFormValue' on 'ElementInternals': The target element is not a form-associated custom element."), K(this), t != null && !(t instanceof FormData)) { | ||
if (e.getAttribute("name")) { | ||
const o = G(e, this); | ||
o.value = t; | ||
} | ||
} else | ||
t != null && t instanceof FormData && Array.from(t).reverse().forEach(([o, i]) => { | ||
if (typeof i == "string") { | ||
const s = G(e, this); | ||
s.name = o, s.value = i; | ||
} | ||
}); | ||
A.set(e, t); | ||
} | ||
setValidity(t, e, o) { | ||
const i = v.get(this); | ||
if (E(i, "Failed to execute 'setValidity' on 'ElementInternals': The target element is not a form-associated custom element."), !t) | ||
throw new TypeError("Failed to execute 'setValidity' on 'ElementInternals': 1 argument required, but only 0 present."); | ||
H.set(this, o); | ||
const s = c.get(this), n = {}; | ||
for (const x in t) | ||
n[x] = t[x]; | ||
Object.keys(n).length === 0 && ht(s); | ||
const u = { ...s, ...n }; | ||
delete u.valid; | ||
const { valid: d } = mt(s, u, this.form); | ||
if (!d && !e) | ||
throw new DOMException("Failed to execute 'setValidity' on 'ElementInternals': The second argument should not be empty if one or more flags in the first argument are true."); | ||
m.set(this, d ? "" : e), i.isConnected ? (i.toggleAttribute("internals-invalid", !d), i.toggleAttribute("internals-valid", d), i.setAttribute("aria-invalid", `${!d}`)) : L.set(i, this); | ||
} | ||
get shadowRoot() { | ||
const t = v.get(this), e = W.get(t); | ||
return e || null; | ||
} | ||
get validationMessage() { | ||
const t = v.get(this); | ||
return E(t, "Failed to read the 'validationMessage' property from 'ElementInternals': The target element is not a form-associated custom element."), m.get(this); | ||
} | ||
get validity() { | ||
const t = v.get(this); | ||
return E(t, "Failed to read the 'validity' property from 'ElementInternals': The target element is not a form-associated custom element."), c.get(this); | ||
} | ||
get willValidate() { | ||
const t = v.get(this); | ||
return E(t, "Failed to read the 'willValidate' property from 'ElementInternals': The target element is not a form-associated custom element."), !(t.disabled || t.hasAttribute("disabled") || t.hasAttribute("readonly")); | ||
} | ||
} | ||
function yt() { | ||
if (typeof window > "u" || !window.ElementInternals || !HTMLElement.prototype.attachInternals) | ||
return !1; | ||
class r extends HTMLElement { | ||
constructor() { | ||
super(), this.internals = this.attachInternals(); | ||
} | ||
} | ||
const t = `element-internals-feature-detection-${Math.random().toString(36).replace(/[^a-z]+/g, "")}`; | ||
customElements.define(t, r); | ||
const e = new r(); | ||
return [ | ||
"shadowRoot", | ||
"form", | ||
"willValidate", | ||
"validity", | ||
"validationMessage", | ||
"labels", | ||
"setFormValue", | ||
"setValidity", | ||
"checkValidity", | ||
"reportValidity" | ||
].every((o) => o in e.internals); | ||
} | ||
if (yt()) { | ||
if (typeof window < "u" && !window.CustomStateSet) { | ||
window.CustomStateSet = V; | ||
const r = HTMLElement.prototype.attachInternals; | ||
HTMLElement.prototype.attachInternals = function(...t) { | ||
const e = r.call(this, t); | ||
return e.states = new V(this), e; | ||
}; | ||
} | ||
} else { | ||
if (typeof window < "u" && (window.ElementInternals = et), typeof CustomElementRegistry < "u") { | ||
const r = CustomElementRegistry.prototype.define; | ||
CustomElementRegistry.prototype.define = function(t, e, o) { | ||
if (e.formAssociated) { | ||
const i = e.prototype.connectedCallback; | ||
e.prototype.connectedCallback = function() { | ||
B.has(this) || (B.set(this, !0), this.hasAttribute("disabled") && $(this, !0)), i != null && i.apply(this), Y(this); | ||
}; | ||
} | ||
r.call(this, t, e, o); | ||
}; | ||
} | ||
if (typeof HTMLElement < "u" && (HTMLElement.prototype.attachInternals = function() { | ||
if (this.tagName) { | ||
if (this.tagName.indexOf("-") === -1) | ||
throw new Error("Failed to execute 'attachInternals' on 'HTMLElement': Unable to attach ElementInternals to non-custom elements."); | ||
} else | ||
return {}; | ||
if (l.has(this)) | ||
throw new DOMException("DOMException: Failed to execute 'attachInternals' on 'HTMLElement': ElementInternals for the specified element was already attached."); | ||
return new et(this); | ||
}), typeof Element < "u") { | ||
let r = function(...e) { | ||
const o = t.apply(this, e); | ||
if (W.set(this, o), S()) { | ||
const i = new MutationObserver(P); | ||
window.ShadyDOM ? i.observe(this, _) : i.observe(o, _), b.set(this, i); | ||
} | ||
return o; | ||
}; | ||
const t = Element.prototype.attachShadow; | ||
Element.prototype.attachShadow = r; | ||
} | ||
S() && typeof document < "u" && new MutationObserver(P).observe(document.documentElement, _), typeof HTMLFormElement < "u" && gt(), typeof window < "u" && !window.CustomStateSet && (window.CustomStateSet = V); | ||
} | ||
})(); | ||
var Ft = Object.defineProperty, Lt = Object.getOwnPropertyDescriptor, g = (v, c, a, l) => { | ||
for (var m = l > 1 ? void 0 : l ? Lt(c, a) : c, y = v.length - 1, b; y >= 0; y--) | ||
(b = v[y]) && (m = (l ? b(c, a, m) : b(m)) || m); | ||
return l && m && Ft(c, a, m), m; | ||
}; | ||
const d = "pie-button"; | ||
class n extends f { | ||
const z = "pie-button"; | ||
class p extends Et { | ||
constructor() { | ||
super(...arguments), this.size = "medium", this.type = "submit", this.variant = "primary", this.iconPlacement = "leading", this.disabled = !1, this.isLoading = !1, this.isFullWidth = !1; | ||
super(), this.size = "medium", this.type = "submit", this.variant = "primary", this.iconPlacement = "leading", this.disabled = !1, this.isLoading = !1, this.isFullWidth = !1, this._internals = this.attachInternals(); | ||
} | ||
get form() { | ||
return this._internals.form; | ||
} | ||
/** | ||
* This method creates an invisible button of the same type as pie-button. It is then clicked, and immediately removed from the DOM. | ||
* This is done so that we trigger native form actions, such as submit and reset in the browser. The performance impact of adding and removing a single button to the DOM | ||
* should be neglible, however this should be monitored. | ||
* This is the only viable way of guaranteeing native button behaviour when using a web component in place of an actual HTML button. | ||
* | ||
* TODO: if we need to repeat this logic elsewhere, then we should consider moving this code to a shared class or mixin. | ||
*/ | ||
_simulateNativeButtonClick(c) { | ||
if (!this.form) | ||
return; | ||
const a = document.createElement("button"); | ||
a.type = c, a.style.position = "absolute", a.style.width = "1px", a.style.height = "1px", a.style.padding = "0", a.style.margin = "-1px", a.style.overflow = "hidden", a.style.border = "0", a.style.whiteSpace = "nowrap", c === "submit" && (this.name && (a.name = this.name), this.value && (a.value = this.value), this.formaction && a.setAttribute("formaction", this.formaction), this.formenctype && a.setAttribute("formenctype", this.formenctype), this.formmethod && a.setAttribute("formmethod", this.formmethod), this.formnovalidate && a.setAttribute("formnovalidate", "formnovalidate"), this.formtarget && a.setAttribute("formtarget", this.formtarget)), this.form.append(a), a.click(), a.remove(); | ||
} | ||
_handleClick() { | ||
!this.isLoading && this.form && (this.type === "submit" && (this.formnovalidate || this.form.reportValidity()) && this._simulateNativeButtonClick("submit"), this.type === "reset" && this._simulateNativeButtonClick("reset")); | ||
} | ||
render() { | ||
const { | ||
type: r, | ||
disabled: t, | ||
isFullWidth: a, | ||
variant: o, | ||
size: e, | ||
isLoading: i, | ||
iconPlacement: l | ||
type: c, | ||
disabled: a, | ||
isFullWidth: l, | ||
variant: m, | ||
size: y, | ||
isLoading: b, | ||
iconPlacement: h | ||
} = this; | ||
return p` | ||
return R` | ||
<button | ||
@click=${this._handleClick} | ||
class="o-btn" | ||
type=${r} | ||
variant=${o} | ||
size=${e} | ||
?disabled=${t} | ||
?isFullWidth=${a} | ||
?isLoading=${i}> | ||
${l === "leading" ? p`<slot name="icon"></slot>` : h} | ||
type=${c} | ||
variant=${m} | ||
size=${y} | ||
?disabled=${a} | ||
?isFullWidth=${l} | ||
?isLoading=${b}> | ||
${h === "leading" ? R`<slot name="icon"></slot>` : ot} | ||
<slot></slot> | ||
${l === "trailing" ? p`<slot name="icon"></slot>` : h} | ||
${h === "trailing" ? R`<slot name="icon"></slot>` : ot} | ||
</button>`; | ||
} | ||
focus() { | ||
var r, t; | ||
(t = (r = this.shadowRoot) == null ? void 0 : r.querySelector("button")) == null || t.focus(); | ||
var c, a; | ||
(a = (c = this.shadowRoot) == null ? void 0 : c.querySelector("button")) == null || a.focus(); | ||
} | ||
} | ||
n.styles = g(u); | ||
s([ | ||
c(), | ||
b(d, y, "medium") | ||
], n.prototype, "size", 2); | ||
s([ | ||
c(), | ||
b(d, z, "submit") | ||
], n.prototype, "type", 2); | ||
s([ | ||
c(), | ||
b(d, x, "primary") | ||
], n.prototype, "variant", 2); | ||
s([ | ||
c({ type: String }), | ||
b(d, w, "leading") | ||
], n.prototype, "iconPlacement", 2); | ||
s([ | ||
c({ type: Boolean }) | ||
], n.prototype, "disabled", 2); | ||
s([ | ||
c({ type: Boolean, reflect: !0 }) | ||
], n.prototype, "isLoading", 2); | ||
s([ | ||
c({ type: Boolean }) | ||
], n.prototype, "isFullWidth", 2); | ||
customElements.define(d, n); | ||
p.formAssociated = !0; | ||
p.styles = wt(At); | ||
g([ | ||
f(), | ||
N(z, xt, "medium") | ||
], p.prototype, "size", 2); | ||
g([ | ||
f(), | ||
N(z, Mt, "submit") | ||
], p.prototype, "type", 2); | ||
g([ | ||
f(), | ||
N(z, kt, "primary") | ||
], p.prototype, "variant", 2); | ||
g([ | ||
f({ type: String }), | ||
N(z, zt, "leading") | ||
], p.prototype, "iconPlacement", 2); | ||
g([ | ||
f({ type: Boolean }) | ||
], p.prototype, "disabled", 2); | ||
g([ | ||
f({ type: Boolean, reflect: !0 }) | ||
], p.prototype, "isLoading", 2); | ||
g([ | ||
f({ type: Boolean }) | ||
], p.prototype, "isFullWidth", 2); | ||
g([ | ||
f({ type: String }) | ||
], p.prototype, "name", 2); | ||
g([ | ||
f({ type: String }) | ||
], p.prototype, "value", 2); | ||
g([ | ||
f() | ||
], p.prototype, "formaction", 2); | ||
g([ | ||
f() | ||
], p.prototype, "formenctype", 2); | ||
g([ | ||
f() | ||
], p.prototype, "formmethod", 2); | ||
g([ | ||
f({ type: Boolean }) | ||
], p.prototype, "formnovalidate", 2); | ||
g([ | ||
f() | ||
], p.prototype, "formtarget", 2); | ||
customElements.define(z, p); | ||
export { | ||
n as PieButton, | ||
w as iconPlacements, | ||
y as sizes, | ||
z as types, | ||
x as variants | ||
p as PieButton, | ||
Tt as formEncodingtypes, | ||
St as formMethodTypes, | ||
Vt as formTargetTypes, | ||
zt as iconPlacements, | ||
xt as sizes, | ||
Mt as types, | ||
kt as variants | ||
}; |
@@ -12,3 +12,3 @@ import type { CSSResult } from 'lit'; | ||
/** | ||
* What type attribute should be applied to the button. For example submit, button or menu. | ||
* What type attribute should be applied to the button. For example submit, button. | ||
*/ | ||
@@ -36,4 +36,48 @@ type: typeof types[number]; | ||
isLoading: boolean; | ||
/** | ||
* The name of the button, submitted as a pair with the button's value as part of the form data, when that button is used to submit the form. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
name?: string; | ||
/** | ||
* Defines the value associated with the button's name when it's submitted with the form data. This value is passed to the server in params when the form is submitted using this button. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
value?: string; | ||
/** | ||
* The URL that processes the information submitted by the button. Overrides the action attribute of the button's form owner. Does nothing if there is no form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formaction?: string; | ||
/** | ||
* If the button is a submit button (it's inside/associated with a <form> and doesn't have type="button"), specifies how to encode the form data that is submitted. | ||
* If this attribute is specified, it overrides the enctype attribute of the button's form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formenctype?: typeof formEncodingtypes[number]; | ||
/** | ||
* If the button is a submit button (it's inside/associated with a <form> and doesn't have type="button"), this attribute specifies the HTTP method used to submit the form. | ||
* If specified, this attribute overrides the method attribute of the button's form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formmethod?: typeof formMethodTypes[number]; | ||
/** | ||
* If the button is a submit button, this Boolean attribute specifies that the form is not to be validated when it is submitted. | ||
* If this attribute is specified, it overrides the novalidate attribute of the button's form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formnovalidate?: boolean; | ||
/** | ||
* If the button is a submit button, this attribute is an author-defined name or standardized, underscore-prefixed keyword indicating where to display the response from submitting the form. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formtarget?: typeof formTargetTypes[number]; | ||
} | ||
export declare const formEncodingtypes: readonly ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]; | ||
export declare const formMethodTypes: readonly ["post", "get", "dialog"]; | ||
export declare const formTargetTypes: readonly ["_self", "_blank", "_parent", "_top"]; | ||
export declare const iconPlacements: readonly ["leading", "trailing"]; | ||
@@ -48,2 +92,6 @@ | ||
declare class PieButton_2 extends LitElement implements ButtonProps { | ||
static formAssociated: boolean; | ||
private readonly _internals; | ||
get form(): HTMLFormElement | null; | ||
constructor(); | ||
size: ButtonProps['size']; | ||
@@ -56,2 +104,19 @@ type: ButtonProps['type']; | ||
isFullWidth: boolean; | ||
name?: string; | ||
value?: string; | ||
formaction: ButtonProps['formaction']; | ||
formenctype: ButtonProps['formenctype']; | ||
formmethod: ButtonProps['formmethod']; | ||
formnovalidate: ButtonProps['formnovalidate']; | ||
formtarget: ButtonProps['formtarget']; | ||
/** | ||
* This method creates an invisible button of the same type as pie-button. It is then clicked, and immediately removed from the DOM. | ||
* This is done so that we trigger native form actions, such as submit and reset in the browser. The performance impact of adding and removing a single button to the DOM | ||
* should be neglible, however this should be monitored. | ||
* This is the only viable way of guaranteeing native button behaviour when using a web component in place of an actual HTML button. | ||
* | ||
* TODO: if we need to repeat this logic elsewhere, then we should consider moving this code to a shared class or mixin. | ||
*/ | ||
private _simulateNativeButtonClick; | ||
private _handleClick; | ||
render(): TemplateResult<1>; | ||
@@ -64,3 +129,3 @@ focus(): void; | ||
export declare const types: readonly ["submit", "button", "reset", "menu"]; | ||
export declare const types: readonly ["submit", "button", "reset"]; | ||
@@ -67,0 +132,0 @@ export declare type Variant = typeof variants[number]; |
@@ -1,4 +0,4 @@ | ||
import * as g from "react"; | ||
import { PieButton as P } from "./index.js"; | ||
import { iconPlacements as k, sizes as D, types as G, variants as O } from "./index.js"; | ||
import * as E from "react"; | ||
import { PieButton as M } from "./index.js"; | ||
import { formEncodingtypes as j, formMethodTypes as k, formTargetTypes as D, iconPlacements as G, sizes as O, types as S, variants as _ } from "./index.js"; | ||
import "lit"; | ||
@@ -11,20 +11,20 @@ import "lit/decorators.js"; | ||
*/ | ||
const b = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), E = /* @__PURE__ */ new WeakMap(), B = (d, l, m, p, u) => { | ||
const s = u == null ? void 0 : u[l]; | ||
s === void 0 || m === p ? m == null && l in HTMLElement.prototype ? d.removeAttribute(l) : d[l] = m : ((i, t, h) => { | ||
let o = E.get(i); | ||
o === void 0 && E.set(i, o = /* @__PURE__ */ new Map()); | ||
let a = o.get(t); | ||
h !== void 0 ? a === void 0 ? (o.set(t, a = { handleEvent: h }), i.addEventListener(t, a)) : a.handleEvent = h : a !== void 0 && (o.delete(t), i.removeEventListener(t, a)); | ||
})(d, s, m); | ||
const P = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), w = /* @__PURE__ */ new WeakMap(), b = (m, r, p, d, u) => { | ||
const o = u == null ? void 0 : u[r]; | ||
o === void 0 || p === d ? p == null && r in HTMLElement.prototype ? m.removeAttribute(r) : m[r] = p : ((s, t, h) => { | ||
let i = w.get(s); | ||
i === void 0 && w.set(s, i = /* @__PURE__ */ new Map()); | ||
let a = i.get(t); | ||
h !== void 0 ? a === void 0 ? (i.set(t, a = { handleEvent: h }), s.addEventListener(t, a)) : a.handleEvent = h : a !== void 0 && (i.delete(t), s.removeEventListener(t, a)); | ||
})(m, o, p); | ||
}; | ||
function M(d = window.React, l, m, p, u) { | ||
let s, i, t; | ||
if (l === void 0) { | ||
const r = d; | ||
({ tagName: i, elementClass: t, events: p, displayName: u } = r), s = r.react; | ||
function B(m = window.React, r, p, d, u) { | ||
let o, s, t; | ||
if (r === void 0) { | ||
const l = m; | ||
({ tagName: s, elementClass: t, events: d, displayName: u } = l), o = l.react; | ||
} else | ||
s = d, t = m, i = l; | ||
const h = s.Component, o = s.createElement, a = new Set(Object.keys(p ?? {})); | ||
class f extends h { | ||
o = m, t = p, s = r; | ||
const h = o.Component, i = o.createElement, a = new Set(Object.keys(d ?? {})); | ||
class v extends h { | ||
constructor() { | ||
@@ -35,4 +35,4 @@ super(...arguments), this.o = null; | ||
if (this.o !== null) | ||
for (const v in this.i) | ||
B(this.o, v, this.props[v], e ? e[v] : void 0, p); | ||
for (const f in this.i) | ||
b(this.o, f, this.props[f], e ? e[f] : void 0, d); | ||
} | ||
@@ -46,22 +46,22 @@ componentDidMount() { | ||
render() { | ||
const { _$Gl: e, ...v } = this.props; | ||
const { _$Gl: e, ...f } = this.props; | ||
this.h !== e && (this.u = (n) => { | ||
e !== null && ((c, w) => { | ||
typeof c == "function" ? c(w) : c.current = w; | ||
e !== null && ((c, g) => { | ||
typeof c == "function" ? c(g) : c.current = g; | ||
})(e, n), this.o = n, this.h = e; | ||
}), this.i = {}; | ||
const y = { ref: this.u }; | ||
for (const [n, c] of Object.entries(v)) | ||
b.has(n) ? y[n === "className" ? "class" : n] = c : a.has(n) || n in t.prototype ? this.i[n] = c : y[n] = c; | ||
return o(i, y); | ||
for (const [n, c] of Object.entries(f)) | ||
P.has(n) ? y[n === "className" ? "class" : n] = c : a.has(n) || n in t.prototype ? this.i[n] = c : y[n] = c; | ||
return i(s, y); | ||
} | ||
} | ||
f.displayName = u ?? t.name; | ||
const N = s.forwardRef((r, e) => o(f, { ...r, _$Gl: e }, r == null ? void 0 : r.children)); | ||
return N.displayName = f.displayName, N; | ||
v.displayName = u ?? t.name; | ||
const N = o.forwardRef((l, e) => i(v, { ...l, _$Gl: e }, l == null ? void 0 : l.children)); | ||
return N.displayName = v.displayName, N; | ||
} | ||
const R = M({ | ||
const L = B({ | ||
displayName: "PieButton", | ||
elementClass: P, | ||
react: g, | ||
elementClass: M, | ||
react: E, | ||
tagName: "pie-button", | ||
@@ -71,7 +71,10 @@ events: {} | ||
export { | ||
R as PieButton, | ||
k as iconPlacements, | ||
D as sizes, | ||
G as types, | ||
O as variants | ||
L as PieButton, | ||
j as formEncodingtypes, | ||
k as formMethodTypes, | ||
D as formTargetTypes, | ||
G as iconPlacements, | ||
O as sizes, | ||
S as types, | ||
_ as variants | ||
}; |
{ | ||
"name": "@justeattakeaway/pie-button", | ||
"version": "0.31.0", | ||
"version": "0.32.0", | ||
"description": "PIE design system button built using web components", | ||
@@ -41,3 +41,6 @@ "type": "module", | ||
"dist/*.js" | ||
] | ||
], | ||
"dependencies": { | ||
"element-internals-polyfill": "1.3.8" | ||
} | ||
} |
@@ -23,3 +23,4 @@ <p align="center"> | ||
- [React example (using Next 13)](#react-templates-using-next-13) | ||
8. [Testing](#testing) | ||
6. [Forms usage](#forms-usage) | ||
7. [Testing](#testing) | ||
- [Browser Tests](#browser-tests) | ||
@@ -100,12 +101,20 @@ - [Visual Tests](#visual-tests) | ||
| Property | Type | Default | Description | | ||
|-------------|-----------|-----------|-------------------------------------------------------------------------------------------------------------------| | ||
| size | `String` | `medium` | Size of the button, one of `sizes` – `xsmall`, `small-expressive`, `small-productive`, `medium`, `large` | | ||
| type | `String` | `submit` | Type of the button, one of `types` – `submit`, `button`, `reset`, `menu` | | ||
| variant | `String` | `primary` | Variant of the button, one of `variants` – `primary`, `secondary`, `outline`, `ghost`, `destructive`, `destructive-ghost`, `inverse`, `ghost-inverse` or `outline-inverse` | | ||
| disabled | `Boolean` | `false` | If `true`, disables the button. | | ||
| isFullWidth | `Boolean` | `false` | If `true`, sets the button width to 100% of its container. | | ||
| isLoading | `Boolean` | `false` | If `true`, displays a loading indicator inside the button. | | ||
| iconPlacement | `String` | `leading` | Icon placements of the icon slot, if provided, one of `iconPlacements` - `leading`, `trailing` | | ||
| Property | Type | Default | Description | | ||
|----------------|-----------|------------|----------------------------------------------------------------------------------------------------------------------| | ||
| size | `String` | `medium` | Size of the button, one of `sizes` – `xsmall`, `small-expressive`, `small-productive`, `medium`, `large` | | ||
| type | `String` | `submit` | Type of the button, one of `types` – `submit`, `button`, `reset`. [Read further on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type)| | ||
| variant | `String` | `primary` | Variant of the button, one of `variants` – `primary`, `secondary`, `outline`, `ghost`, `destructive`, `destructive-ghost`, `inverse`, `ghost-inverse`, `outline-inverse` | | ||
| disabled | `Boolean` | `false` | If `true`, disables the button. | | ||
| isFullWidth | `Boolean` | `false` | If `true`, sets the button width to 100% of its container. | | ||
| isLoading | `Boolean` | `false` | If `true`, displays a loading indicator inside the button. | | ||
| iconPlacement | `String` | `leading` | Icon placements of the icon slot, if provided, one of `iconPlacements` - `leading`, `trailing` | | ||
| name | `String` | `undefined`| The name of the button, to be submitted with form data. [Read further on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-name) | | ||
| value | `String` | `undefined`| The value of the button, to be submitted with form data. [Read further on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-value) | | ||
| formaction | `String` | `undefined`| Designates an alternative URL for form data submission. [Read further on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-formaction) | | ||
| formenctype | `String` | `undefined`| Specifies the form data encoding type. [Read further on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-formenctype) | | ||
| formmethod | `String` | `undefined`| Sets the HTTP method for form data. [Read further on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-formmethod) | | ||
| formnovalidate | `Boolean` | `undefined` | Ensures the form is submitted without native HTML validation. [Read further on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-formnovalidate) | | ||
| formtarget | `String` | `undefined`| Dictates where to display the response after form submission. [Read further on MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-formtarget) | | ||
In your markup or JSX, you can then use these to set the properties for the `pie-button` component: | ||
@@ -173,2 +182,44 @@ | ||
## Forms usage | ||
The `pie-button` web component is designed to integrate with standard HTML forms just like a native HTML button. When positioned inside a form, the component will automatically associate itself, enabling it to directly interact with the form context. | ||
### Button Attributes | ||
The `pie-button` provides a set of attributes to customize its behavior within forms: | ||
- `type`: Determines the button's function. Set to `submit` for form submissions or `reset` to clear form fields. | ||
- `formaction`: Designates an alternative URL for form data submission when this specific button is clicked. | ||
- `formenctype`: Specifies the form data encoding type during submission via this button. | ||
- `formmethod`: Sets the HTTP method (e.g., GET or POST) for form data when initiated by this button. | ||
- `formnovalidate`: If present, ensures the form is submitted without validation checks. | ||
- `formtarget`: Dictates where to display the response after form submission. | ||
Please see the [MDN docs]((https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes)) for more information on these attributes. | ||
### Integration Example | ||
```html | ||
<form action="/default-endpoint" method="post"> | ||
<input type="text" name="username" required> | ||
<pie-button | ||
type="submit" | ||
formaction="/alternate-endpoint" | ||
formenctype="multipart/form-data" | ||
formmethod="post" | ||
formnovalidate | ||
formtarget="_blank"> | ||
Submit | ||
</pie-button> | ||
</form> | ||
``` | ||
In this example: | ||
- The pie-button, when clicked, will send the form data to /alternate-endpoint instead of the form's default /default-endpoint. | ||
- It uses the multipart/form-data encoding type for form submission. | ||
- The form will submit using the POST method. | ||
- No validation will be performed during submission, thanks to formnovalidate. | ||
- The form's submission response will be opened in a new browser tab/window because of the formtarget="_blank" attribute. | ||
## Testing | ||
@@ -175,0 +226,0 @@ |
export const sizes = ['xsmall', 'small-productive', 'small-expressive', 'medium', 'large'] as const; | ||
export const types = ['submit', 'button', 'reset', 'menu'] as const; | ||
export const types = ['submit', 'button', 'reset'] as const; | ||
export const variants = [ | ||
@@ -11,2 +11,6 @@ 'primary', 'secondary', 'outline', 'outline-inverse', 'ghost', | ||
export const formEncodingtypes = ['application/x-www-form-urlencoded', 'multipart/form-data', 'text/plain'] as const; | ||
export const formMethodTypes = ['post', 'get', 'dialog'] as const; | ||
export const formTargetTypes = ['_self', '_blank', '_parent', '_top'] as const; | ||
export interface ButtonProps { | ||
@@ -18,3 +22,3 @@ /** | ||
/** | ||
* What type attribute should be applied to the button. For example submit, button or menu. | ||
* What type attribute should be applied to the button. For example submit, button. | ||
*/ | ||
@@ -42,2 +46,47 @@ type: typeof types[number]; | ||
isLoading: boolean; | ||
/** | ||
* The name of the button, submitted as a pair with the button's value as part of the form data, when that button is used to submit the form. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
name?: string; | ||
/** | ||
* Defines the value associated with the button's name when it's submitted with the form data. This value is passed to the server in params when the form is submitted using this button. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
value?: string; | ||
/** | ||
* The URL that processes the information submitted by the button. Overrides the action attribute of the button's form owner. Does nothing if there is no form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formaction?: string; | ||
/** | ||
* If the button is a submit button (it's inside/associated with a <form> and doesn't have type="button"), specifies how to encode the form data that is submitted. | ||
* If this attribute is specified, it overrides the enctype attribute of the button's form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formenctype?: typeof formEncodingtypes[number] | ||
/** | ||
* If the button is a submit button (it's inside/associated with a <form> and doesn't have type="button"), this attribute specifies the HTTP method used to submit the form. | ||
* If specified, this attribute overrides the method attribute of the button's form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formmethod?: typeof formMethodTypes[number] | ||
/** | ||
* If the button is a submit button, this Boolean attribute specifies that the form is not to be validated when it is submitted. | ||
* If this attribute is specified, it overrides the novalidate attribute of the button's form owner. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formnovalidate?: boolean; | ||
/** | ||
* If the button is a submit button, this attribute is an author-defined name or standardized, underscore-prefixed keyword indicating where to display the response from submitting the form. | ||
* [MDN reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attributes) | ||
*/ | ||
formtarget?: typeof formTargetTypes[number] | ||
} |
107
src/index.ts
@@ -6,6 +6,7 @@ import { | ||
import { validPropertyValues } from '@justeattakeaway/pie-webc-core'; | ||
import styles from './button.scss?inline'; | ||
import { | ||
ButtonProps, sizes, types, variants, iconPlacements, | ||
} from './defs'; | ||
import styles from './button.scss?inline'; | ||
import 'element-internals-polyfill'; | ||
@@ -22,2 +23,16 @@ // Valid values available to consumers | ||
export class PieButton extends LitElement implements ButtonProps { | ||
// TODO - we may want to consider making the element internals code reusable for other form controls. | ||
static formAssociated = true; | ||
private readonly _internals: ElementInternals; | ||
public get form () { | ||
return this._internals.form; | ||
} | ||
constructor () { | ||
super(); | ||
this._internals = this.attachInternals(); | ||
} | ||
@property() | ||
@@ -48,2 +63,91 @@ @validPropertyValues(componentSelector, sizes, 'medium') | ||
@property({ type: String }) | ||
public name?: string; | ||
@property({ type: String }) | ||
public value?: string; | ||
@property() | ||
public formaction: ButtonProps['formaction']; | ||
@property() | ||
public formenctype: ButtonProps['formenctype']; | ||
@property() | ||
public formmethod: ButtonProps['formmethod']; | ||
@property({ type: Boolean }) | ||
public formnovalidate: ButtonProps['formnovalidate']; | ||
@property() | ||
public formtarget: ButtonProps['formtarget']; | ||
/** | ||
* This method creates an invisible button of the same type as pie-button. It is then clicked, and immediately removed from the DOM. | ||
* This is done so that we trigger native form actions, such as submit and reset in the browser. The performance impact of adding and removing a single button to the DOM | ||
* should be neglible, however this should be monitored. | ||
* This is the only viable way of guaranteeing native button behaviour when using a web component in place of an actual HTML button. | ||
* | ||
* TODO: if we need to repeat this logic elsewhere, then we should consider moving this code to a shared class or mixin. | ||
*/ | ||
private _simulateNativeButtonClick (btnType: 'submit' | 'reset') { | ||
if (!this.form) return; | ||
const btn = document.createElement('button'); | ||
btn.type = btnType; | ||
// Visually hidden styles | ||
btn.style.position = 'absolute'; | ||
btn.style.width = '1px'; | ||
btn.style.height = '1px'; | ||
btn.style.padding = '0'; | ||
btn.style.margin = '-1px'; | ||
btn.style.overflow = 'hidden'; | ||
btn.style.border = '0'; | ||
btn.style.whiteSpace = 'nowrap'; | ||
if (btnType === 'submit') { | ||
if (this.name) { | ||
btn.name = this.name; | ||
} | ||
if (this.value) { | ||
btn.value = this.value; | ||
} | ||
if (this.formaction) { | ||
btn.setAttribute('formaction', this.formaction); | ||
} | ||
if (this.formenctype) { | ||
btn.setAttribute('formenctype', this.formenctype); | ||
} | ||
if (this.formmethod) { | ||
btn.setAttribute('formmethod', this.formmethod); | ||
} | ||
if (this.formnovalidate) { | ||
btn.setAttribute('formnovalidate', 'formnovalidate'); | ||
} | ||
if (this.formtarget) { | ||
btn.setAttribute('formtarget', this.formtarget); | ||
} | ||
} | ||
this.form.append(btn); | ||
btn.click(); | ||
btn.remove(); | ||
} | ||
private _handleClick () { | ||
if (!this.isLoading && this.form) { | ||
if (this.type === 'submit') { | ||
// only submit the form if either formnovalidate is set, or the form passes validation checks (triggers native form validation) | ||
if (this.formnovalidate || this.form.reportValidity()) { | ||
this._simulateNativeButtonClick('submit'); | ||
} | ||
} | ||
if (this.type === 'reset') { | ||
this._simulateNativeButtonClick('reset'); | ||
} | ||
} | ||
} | ||
render () { | ||
@@ -62,2 +166,3 @@ const { | ||
<button | ||
@click=${this._handleClick} | ||
class="o-btn" | ||
@@ -64,0 +169,0 @@ type=${type} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
85109
1230
255
1
1
+ Addedelement-internals-polyfill@1.3.8(transitive)