@coderundebug/ui-web
Version:
A collection of UI web components that can be used in any web project.
2 lines • 11.7 kB
JavaScript
/* By Stephen Paul Hassall (web: https://coderundebug.com) */
import{UiTools as e}from"./ui-tools.js";export class UiMenuGroup extends HTMLElement{static get formAssociated(){return!0}constructor(){super(),this.attachShadow({mode:"open",delegatesFocus:!0}),this.shadowRoot.innerHTML=UiMenuGroup.uiHtml,this.shadowRoot.adoptedStyleSheets=[UiMenuGroup.uiCssStyleSheet],this.o=this.attachInternals(),this.i=this.shadowRoot.querySelector(".item"),this.t=this.shadowRoot.querySelector("a"),this.u=this.shadowRoot.getElementById("chevron-button"),this.l=this.shadowRoot.getElementById("group"),this.h=this.h.bind(this),this.m=this.m.bind(this)}get disabled(){return!1!==this.hasAttribute("disabled")}set disabled(e){if(!0===e)this.setAttribute("disabled",""),this.t.removeAttribute("href");else{this.removeAttribute("disabled");const e=this.getAttribute("href");this.t.setAttribute("href",e)}}get href(){return this.t.href}attributeChangedCallback(e,o,i){"indent"!==e?!0!==e.startsWith("arrow-")&&this.t.setAttribute(e,i):this.p()}static get observedAttributes(){return["indent","href","hreflang","download","ping","referrerpolicy","rel","target","type"]}connectedCallback(){this.v(),this.t.addEventListener("click",this.h),this.u.addEventListener("click",this.m),this.l.addEventListener("click",this.k)}disconnectedCallback(){this.t.removeEventListener("click",this.h),this.u.removeEventListener("click",this.m),this.l.removeEventListener("click",this.k)}h(){!0!==this.hasAttribute("href")&&this.u.click()}m(e){!0===this.hasAttribute("open")?this.removeAttribute("open"):this.setAttribute("open",""),e.stopPropagation()}k(e){e.stopPropagation()}formDisabledCallback(e){if(!0===e)this.t.removeAttribute("href");else{const e=this.getAttribute("href");this.t.setAttribute("href",e)}}p(){if(!1===this.hasAttribute("indent"))this.t.removeAttribute("style");else{let e=this.getAttribute("indent");e||(e=1);const o=parseInt(e);if(o<1||o>20)return;this.t.setAttribute("style","--ui-menu-indent: "+e.toString()+";")}}v(){const e=this.closest("ui-popup-menu, ui-side-menu, ui-content-menu, ui-header-menu");this.i.classList.remove("inside-popup-menu"),this.i.classList.remove("inside-side-menu"),this.i.classList.remove("inside-content-menu"),this.i.classList.remove("inside-header-menu"),e&&("UI-POPUP-MENU"===e.tagName&&this.i.classList.add("inside-popup-menu"),"UI-SIDE-MENU"===e.tagName&&this.i.classList.add("inside-side-menu"),"UI-CONTENT-MENU"===e.tagName&&this.i.classList.add("inside-content-menu"),"UI-HEADER-MENU"===e.tagName&&this.i.classList.add("inside-header-menu"))}}UiMenuGroup.uiCss=' .item{display:flex;flex-direction:row;border-style:none;}:host([arrow-left]) .item{flex-direction:row-reverse;}:host([arrow-hide]:not([href])) .item-chevron{display:none;}.item{--ui-menu-group-background:var(--ui-background, hsl(0 0% 97% / 1));--ui-menu-group-foreground:var(--ui-foreground, hsl(0 0% 18% / 1));background-color:var(--ui-menu-group-background);color:var(--ui-menu-group-foreground);--ui-icon-primary-color:var(--ui-menu-group-foreground);--ui-menu-group-arrow-size:32px;}.item-button{flex:1 1 0;min-width:0;display:flex;gap:8px;align-items:center;width:100%;font-family:inherit;font-size:var(--ui-font-size-normal, 16px);font-weight:var(--ui-font-weight-normal, normal);line-height:150%;text-shadow:inherit;text-overflow:inherit;user-select:none;-webkit-user-select:none;white-space:nowrap;background-color:var(--ui-menu-group-background);color:var(--ui-menu-group-foreground);--ui-icon-primary-color:var(--ui-menu-group-foreground);border:none;box-sizing:border-box;padding:4px 8px;-webkit-tap-highlight-color:transparent;}slot[name="start"]::slotted(*:not(ui-lozenge):not(ui-button):not(ui-icon-button)), slot[name="end"]::slotted(*:not(ui-lozenge):not(ui-button):not(ui-icon-button)){height:16px;width:16px;}.item.inside-side-menu .item-button{gap:var(--ui-menu-side-gap, 8px);font-size:var(--ui-menu-side-font-size, var(--ui-font-size-normal, 16px));font-weight:var(--ui-menu-side-font-weight, var(--ui-font-weight-normal, normal));padding:var(--ui-menu-side-padding, 4px 8px);& slot[name="start"]::slotted(*:not(ui-lozenge):not(ui-button):not(ui-icon-button)), slot[name="end"]::slotted(*:not(ui-lozenge):not(ui-button):not(ui-icon-button)){height:var(--ui-menu-side-icon-size, 16px);width:var(--ui-menu-side-icon-size, 16px);}} .item.inside-side-menu{--ui-menu-group-background:var(--ui-menu-side-background, var(--ui-background, hsl(0 0% 97% / 1)));--ui-menu-group-foreground:var(--ui-menu-side-foreground, var(--ui-foreground, hsl(0 0% 18% / 1)));--ui-menu-group-arrow-size:var(--ui-menu-group-side-arrow-size, 32px);border-inline-start-style:solid;border-inline-start-width:var(--ui-menu-side-bar-width, 4px);border-inline-start-color:var(--ui-menu-side-bar-color, transparent);}.item.inside-content-menu .item-button{gap:var(--ui-menu-content-gap, 8px);font-size:var(--ui-menu-content-font-size, var(--ui-font-size-small, 12px));font-weight:var(--ui-menu-content-font-weight, var(--ui-font-weight-normal, normal));padding:var(--ui-menu-content-padding, 4px 8px);& slot[name="start"]::slotted(*:not(ui-lozenge):not(ui-button):not(ui-icon-button)), slot[name="end"]::slotted(*:not(ui-lozenge):not(ui-button):not(ui-icon-button)){height:var(--ui-menu-content-icon-size, 16px);width:var(--ui-menu-content-icon-size, 16px);}} .item.inside-content-menu{--ui-menu-group-background:var(--ui-menu-content-background, var(--ui-background, hsl(0 0% 97% / 1)));--ui-menu-group-foreground:var(--ui-menu-content-foreground, var(--ui-foreground, hsl(0 0% 18% / 1)));--ui-menu-group-arrow-size:var(--ui-menu-group-content-arrow-size, 32px);border-inline-start-style:solid;border-inline-start-width:var(--ui-menu-content-bar-width, 2px);border-inline-start-color:var(--ui-menu-content-bar-color, var(--ui-midground, hsl(0 0% 90% / 1)));}.item.inside-popup-menu .item-button{gap:var(--ui-menu-popup-gap, 8px);font-size:var(--ui-menu-popup-font-size, var(--ui-font-size-normal, 16px));font-weight:var(--ui-menu-popup-font-weight, var(--ui-font-weight-normal, normal));padding:var(--ui-menu-popup-padding, 4px 8px);& slot[name="start"]::slotted(*:not(ui-lozenge):not(ui-button):not(ui-icon-button)), slot[name="end"]::slotted(*:not(ui-lozenge):not(ui-button):not(ui-icon-button)){height:var(--ui-menu-popup-icon-size, 16px);width:var(--ui-menu-popup-icon-size, 16px);}} .item.inside-popup-menu{--ui-menu-group-background:var(--ui-menu-popup-background, var(--ui-module-background, hsl(0 0% 97% / 1)));--ui-menu-group-foreground:var(--ui-menu-popup-foreground, var(--ui-module-foreground, hsl(0 0% 18% / 1)));--ui-menu-group-arrow-size:var(--ui-menu-group-popup-arrow-size, 32px);border-inline-start-style:solid;border-inline-start-width:var(--ui-menu-popup-bar-width, 0);border-inline-start-color:var(--ui-menu-popup-bar-color, transparent);}.item.inside-header-menu .item-button{gap:var(--ui-menu-header-gap, 8px);font-size:var(--ui-menu-header-font-size, var(--ui-font-size-normal, 16px));font-weight:var(--ui-menu-header-font-weight, var(--ui-font-weight-normal, normal));padding:var(--ui-menu-header-padding, 4px 8px);& slot[name="start"]::slotted(*:not(ui-lozenge):not(ui-button):not(ui-icon-button)), slot[name="end"]::slotted(*:not(ui-lozenge):not(ui-button):not(ui-icon-button)){height:var(--ui-menu-header-icon-size, 16px);width:var(--ui-menu-header-icon-size, 16px);}} .item.inside-header-menu{--ui-menu-group-background:var(--ui-menu-header-background, var(--ui-background, hsl(0 0% 97% / 1)));--ui-menu-group-foreground:var(--ui-menu-header-foreground, var(--ui-foreground, hsl(0 0% 18% / 1)));--ui-menu-group-arrow-size:0;border-inline-start-style:none;}:host([selected]) .item{--ui-menu-group-background:var(--ui-menu-selected-background, var(--ui-selected-background, hsl(215 50% 90% / 1)));--ui-menu-group-foreground:var(--ui-menu-selected-foreground, var(--ui-selected-foreground, hsl(215 50% 30% / 1)));border-color:var(--ui-menu-selected-bar-color, var(--ui-selected-foreground, hsl(215 50% 30% / 1)));}:host(:not([disabled])) .item-button{color:var(--ui-menu-group-foreground);--ui-icon-primary-color:var(--ui-menu-group-foreground);}:host([indent]) .item-button{padding-inline-start:calc(var(--ui-menu-indent-width, 24px) * var(--ui-menu-indent, 1));}.item-button:link, .item-button:visited, .item-button:active{text-decoration:none;}.body{flex-grow:1;text-align:start;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}slot[name="start"]::slotted(*), slot[name="end"]::slotted(*){flex-grow:0;}:host([disabled]) .item-button{color:var( --ui-menu-disabled-foreground, color-mix( in srgb-linear, var(--ui-foreground, hsl(0 0% 18% / 1)) 50%, var(--ui-background, hsl(0 0% 97% / 1)) 50% ) );--ui-icon-primary-color:var( --ui-menu-disabled-foreground, color-mix( in srgb-linear, var(--ui-foreground, hsl(0 0% 18% / 1)) 50%, var(--ui-background, hsl(0 0% 97% / 1)) 50% ) );}.item-chevron{flex-grow:0;display:flex;align-items:center;}#chevron-button{cursor:pointer;border-style:none;background-color:transparent;box-sizing:content-box;display:grid;justify-items:center;align-items:center;width:var(--ui-menu-group-arrow-size);height:var(--ui-menu-group-arrow-size);min-height:100%;padding:0;}#chevron-button > svg{height:calc(var(--ui-menu-group-arrow-size) / 2);transform:rotate(0deg) scaleX(calc(var(--ui-menu-group-icon-scale-arrow-left, -1) * var(--ui-menu-group-icon-scale-rtl, 1)));transition:transform var(--ui-animation-duration-default, 200ms) ease-in-out;}:host(:not([open])) #group{display:none;}:host([open]) #group{display:block;}:host([open]) #chevron-button > svg{transform:rotate(calc(90deg * calc(var(--ui-menu-group-icon-scale-arrow-left, -1) * var(--ui-menu-group-icon-scale-rtl, 1)))) scaleX(calc(var(--ui-menu-group-icon-scale-arrow-left, -1) * var(--ui-menu-group-icon-scale-rtl, 1)));}.item-chevron:active{filter:brightness(75%);}button:focus-visible, a:focus-visible{outline-offset:-3px;outline-style:solid;outline-width:3px;outline-color:var(--ui-foreground, hsl(0 0% 18% / 1));}:host([selected]) button:focus-visible, :host([selected]) a:focus-visible{outline-color:var(--ui-selected-foreground, hsl(215 50% 30% / 1));}@media (hover:hover){:host([arrow-button]) .item-button:hover{cursor:pointer;filter:brightness(85%);}:host([arrow-button]) .item:hover .item-chevron{border-radius:var(--ui-border-radius-normal, 4px);background-color:var(--ui-menu-group-foreground);color:var(--ui-menu-group-background);--ui-icon-primary-color:var(--ui-menu-group-background);}:host(:not([arrow-button])) .item:hover{cursor:pointer;filter:brightness(85%);}:host(:not([disabled])[href]) .item-button:hover .body{text-decoration:var(--ui-menu-group-link-hover-decoration, underline);}:host([disabled][arrow-button]) .item-button{cursor:not-allowed;}} :host([arrow-button]) .item-button:active{filter:brightness(65%);}:host(:not([arrow-button])) .item:active{filter:brightness(65%);}:host([arrow-left]) svg{--ui-menu-group-icon-scale-arrow-left:1;}svg:dir(rtl){--ui-menu-group-icon-scale-rtl:-1;}@media (forced-colors:active) or (prefers-contrast:more){button{border:none;}} ',UiMenuGroup.uiHtml='<div class="item"><a class="item-button"><slot name="start"></slot><div class="body"><slot></slot></div><slot name="end"></slot></a><div class="item-chevron"><button id="chevron-button" type="button"><svg viewBox="0 0 16 16" style=" display: block; min-width: 16px; min-height: 16px; fill: none; stroke: var(--ui-icon-primary-color); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;"><path d="m 6,4 4,4 -4,4"></path></svg></button></div></div><div id="group"><slot name="group"></slot></div>',e.createUi(UiMenuGroup,"ui-menu-group",import.meta.url);