@spectrum-web-components/action-group
Version:
`sp-action-group` delivers a set of action buttons in horizontal or vertical orientation while ensuring the appropriate spacing between those buttons. The `compact` attribute merges these buttons so that they are visually joined to clarify their relations
5 lines (4 loc) • 6.55 kB
JavaScript
"use strict";var f=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var a=(d,u,e,s)=>{for(var t=s>1?void 0:s?b(u,e):u,i=d.length-1,l;i>=0;i--)(l=d[i])&&(t=(s?l(u,e,t):l(t))||t);return s&&t&&f(u,e,t),t};import{html as m,SizedMixin as v,SpectrumElement as p}from"@spectrum-web-components/base";import{property as o,query as g}from"@spectrum-web-components/base/src/decorators.js";import{ActionButton as c}from"@spectrum-web-components/action-button";import{RovingTabindexController as y}from"@spectrum-web-components/reactive-controllers/src/RovingTabindex.js";import{MutationController as S}from"@lit-labs/observers/mutation-controller.js";import C from"./action-group.css.js";const h=[];export class ActionGroup extends v(p,{validSizes:["xs","s","m","l","xl"],noDefaultSize:!0}){constructor(){super();this._buttons=[];this._buttonSelector="sp-action-button, sp-action-menu";this.rovingTabindexController=new y(this,{focusInIndex:e=>{let s=-1;const t=e.findIndex((i,l)=>(!e[s]&&!i.disabled&&(s=l),i.selected&&!i.disabled));return e[t]?t:s},elements:()=>this.buttons,hostDelegatesFocus:!0,isFocusableElement:e=>!e.disabled});this.compact=!1;this.emphasized=!1;this.justified=!1;this.label="";this.quiet=!1;this.vertical=!1;this._selected=h;this.hasManaged=!1;this.manageButtons=()=>{if(!this.slotElement)return;const s=this.slotElement.assignedElements({flatten:!0}).reduce((t,i)=>{if(i.matches(this._buttonSelector))t.push(i);else{const l=Array.from(i.querySelectorAll(`:scope > ${this._buttonSelector}`));t.push(...l)}return t},[]);if(this.buttons=s,this.selects||!this.hasManaged){const t=[];this.buttons.forEach(i=>{i.selected&&t.push(i.value)}),this.setSelected(this.selected.concat(t))}this.manageChildren(),this.manageSelects(),this.hasManaged=!0};new S(this,{config:{childList:!0,subtree:!0},callback:()=>{this.manageButtons()},skipInitial:!0})}static get styles(){return[C]}set buttons(e){e!==this.buttons&&(this._buttons=e,this.rovingTabindexController.clearElementCache())}get buttons(){return this._buttons}set selected(e){this.requestUpdate("selected",this._selected),this._selected=e,this.updateComplete.then(()=>{this.applySelects(),this.manageChildren()})}get selected(){return this._selected}dispatchChange(e){this.dispatchEvent(new Event("change",{bubbles:!0,composed:!0,cancelable:!0}))||(this.setSelected(e),this.buttons.map(t=>{t.selected=this.selected.includes(t.value)}))}setSelected(e,s){if(e===this.selected)return;const t=this.selected;this.requestUpdate("selected",t),this._selected=e,s&&this.dispatchChange(t)}focus(e){this.rovingTabindexController.focus(e)}deselectSelectedButtons(){this.buttons.forEach(e=>{e.selected&&(e.selected=!1,e.tabIndex=-1,e.setAttribute(this.selects?"aria-checked":"aria-pressed","false"))})}handleActionButtonChange(e){e.stopPropagation(),e.preventDefault()}handleClick(e){const s=e.target;if(typeof s.value!="undefined")switch(this.selects){case"single":{this.deselectSelectedButtons(),s.selected=!0,s.tabIndex=0,s.setAttribute("aria-checked","true"),this.setSelected([s.value],!0);break}case"multiple":{const t=[...this.selected];s.selected=!s.selected,s.setAttribute("aria-checked",s.selected?"true":"false"),s.selected?t.push(s.value):t.splice(this.selected.indexOf(s.value),1),this.setSelected(t,!0),this.buttons.forEach(i=>{i.tabIndex=-1}),s.tabIndex=0;break}default:break}}async applySelects(){await this.manageSelects(!0)}async manageSelects(e){if(!this.buttons.length)return;const s=this.buttons;switch(this.selects){case"single":{this.setAttribute("role","radiogroup");const t=[],i=s.map(async r=>{await r.updateComplete,r instanceof c&&r.setAttribute("role","radio"),r.setAttribute("aria-checked",r.selected?"true":"false"),r.selected&&t.push(r)});if(e)break;await Promise.all(i);const l=t.map(r=>r.value);this.setSelected(l||h);break}case"multiple":{this.getAttribute("role")==="radiogroup"&&this.removeAttribute("role");const t=[],i=[],l=s.map(async n=>{await n.updateComplete,n instanceof c&&n.setAttribute("role","checkbox"),n.setAttribute("aria-checked",n.selected?"true":"false"),n.selected&&(t.push(n.value),i.push(n))});if(e)break;await Promise.all(l);const r=t.length?t:h;this.setSelected(r);break}default:if(this.selected.length){const t=[],i=s.map(async l=>{await l.updateComplete,l instanceof c&&l.setAttribute("role","button"),l.selected?(l.setAttribute("aria-pressed","true"),t.push(l)):l.removeAttribute("aria-pressed")});if(e)break;await Promise.all(i),this.setSelected(t.map(l=>l.value))}else{this.buttons.forEach(t=>{t instanceof c&&t.setAttribute("role","button")});break}}this.hasAttribute("role")||this.setAttribute("role","toolbar")}render(){return m`
<slot role="presentation" =${this.manageButtons}></slot>
`}firstUpdated(e){super.firstUpdated(e),this.addEventListener("click",this.handleClick)}updated(e){super.updated(e),e.has("selects")&&(this.manageSelects(),this.manageChildren(),this.selects?this.shadowRoot.addEventListener("change",this.handleActionButtonChange):this.shadowRoot.removeEventListener("change",this.handleActionButtonChange)),(e.has("quiet")||e.has("emphasized")||e.has("size")||e.has("staticColor"))&&this.manageChildren(e),e.has("label")&&(this.label||typeof e.get("label")!="undefined")&&(this.label.length?this.setAttribute("aria-label",this.label):this.removeAttribute("aria-label"))}manageChildren(e){this.buttons.forEach(s=>{(this.quiet||e!=null&&e.get("quiet"))&&(s.quiet=this.quiet),(this.emphasized||e!=null&&e.get("emphasized"))&&(s.emphasized=this.emphasized),(this.staticColor||e!=null&&e.get("staticColor"))&&(s.staticColor=this.staticColor),(this.selects||!this.hasManaged)&&(s.selected=this.selected.includes(s.value)),this.size&&(this.size!=="m"||typeof(e==null?void 0:e.get("size"))!="undefined")&&(s.size=this.size)})}}ActionGroup.shadowRootOptions={...p.shadowRootOptions,delegatesFocus:!0},a([o({type:Boolean,reflect:!0})],ActionGroup.prototype,"compact",2),a([o({type:Boolean,reflect:!0})],ActionGroup.prototype,"emphasized",2),a([o({type:Boolean,reflect:!0})],ActionGroup.prototype,"justified",2),a([o({type:String})],ActionGroup.prototype,"label",2),a([o({type:Boolean,reflect:!0})],ActionGroup.prototype,"quiet",2),a([o({type:String})],ActionGroup.prototype,"selects",2),a([o({reflect:!0,attribute:"static-color"})],ActionGroup.prototype,"staticColor",2),a([o({type:Boolean,reflect:!0})],ActionGroup.prototype,"vertical",2),a([o({type:Array})],ActionGroup.prototype,"selected",1),a([g("slot")],ActionGroup.prototype,"slotElement",2);
//# sourceMappingURL=ActionGroup.js.map