UNPKG

@sandlada/mdc

Version:

@sandlada/mdc is an open source component library that follows the Material Design 3 design specifications.

24 lines 4.66 kB
import{property as e}from"../../../node_modules/@lit/reactive-element/decorators/property.js";import{queryAssignedElements as t}from"../../../node_modules/@lit/reactive-element/decorators/query-assigned-elements.js";import"../../../node_modules/lit/decorators.js";import{html as n}from"../../../node_modules/lit-html/lit-html.js";import{LitElement as r}from"../../../node_modules/lit-element/lit-element.js";import"../../../node_modules/lit/index.js";import i from"../../../_virtual/_@oxc-project_runtime@0.144.0/helpers/esm/decorate.js";import{CAROUSEL_ACTIVE_CHANGE_EVENT as a}from"../carousel.interface.js";import{CarouselStyles as o}from"../carousel.style.js" /** * @license * Copyright 2026 Kai-Orion & Sandlada * SPDX-License-Identifier: MIT * * @fileoverview * Internal base class for `mdc-carousel` — the horizontal scroll-snap * container that owns layout and focal tracking for its `mdc-carousel-item` * children. * * Item widths follow the Jetpack Compose Material 3 carousel formulas: * the large item targets `preferred-item-width`, the small item clamps to * roughly a third of it (40–56px, `CarouselDefaults.Min/MaxSmallItemSize`) * and the medium item is their average. Sizes are recomputed on container * resize and published as `--_carousel-computed-*` custom properties that the * items consume via `--_item-width-*`. * * The focal item is the cell resting at the leading keyline (inline-start * padding position); it is tracked across scroll and surfaced through the * `carousel-active-change` event and the reflected `active` attribute. */ ;var s=class extends r{static{this.styles=o}get activeIndex(){return this.activeIndexValue}constructor(){super(),this.variant=`multi-browse`,this.preferredItemWidth=186,this.items=[],this.resizeObserver=null,this.scrollRafId=null,this.activeIndexValue=-1,this.handleSlotChange=()=>{if(this.items=this.assignedItems,!this.items.length){this.activeIndexValue=-1;return}for(let[e,t]of this.items.entries())t.index=e;this.computeSizes()},this.handleScroll=()=>{this.scrollRafId===null&&(this.scrollRafId=requestAnimationFrame(()=>{this.scrollRafId=null,this.updateActiveItem()}))},this.handleKeydown=e=>{if(e.defaultPrevented)return;let{key:t}=e;if(t===`ArrowLeft`||t===`ArrowRight`){e.preventDefault();let n=t===`ArrowLeft`?-1:1,r=this.activeIndexValue+n;r>=0&&r<this.items.length&&this.scrollToItem(r)}else(t===`Home`||t===`End`)&&(e.preventDefault(),this.scrollToItem(t===`Home`?0:this.items.length-1))},this.getAttribute(`role`)||this.setAttribute(`role`,`group`),this.getAttribute(`aria-label`)||this.setAttribute(`aria-label`,`Carousel`),this.getAttribute(`tabindex`)||this.setAttribute(`tabindex`,`0`),this.addEventListener(`scroll`,this.handleScroll,{passive:!0}),this.addEventListener(`keydown`,this.handleKeydown)}connectedCallback(){super.connectedCallback(),this.resizeObserver=new ResizeObserver(()=>this.computeSizes()),this.resizeObserver.observe(this)}disconnectedCallback(){super.disconnectedCallback(),this.resizeObserver?.disconnect(),this.resizeObserver=null}scrollToItem(e){let t=this.items[e];t&&t.scrollIntoView({block:`nearest`,inline:`start`,behavior:`smooth`})}render(){return n`<slot @slotchange="${this.handleSlotChange}"></slot>`}updated(e){super.updated(e),e.has(`preferredItemWidth`)&&this.computeSizes()}computeSizes(){let e=this.clientWidth;if(e===0)return;let t=Math.min(this.preferredItemWidth,e),n=Math.min(56,Math.max(40,Math.round(t/3))),r=Math.round((t+n)/2);this.style.setProperty(`--_carousel-computed-large`,`${t}px`),this.style.setProperty(`--_carousel-computed-medium`,`${r}px`),this.style.setProperty(`--_carousel-computed-small`,`${n}px`),this.updateActiveItem()}updateActiveItem(){let{items:e}=this;if(!e.length)return;let t=this.matches(`:dir(rtl)`)||getComputedStyle(this).direction===`rtl`,n=t?this.getBoundingClientRect().right-this.leadingPadding:this.getBoundingClientRect().left+this.leadingPadding,r=0,i=1/0;for(let[a,o]of e.entries()){let e=o.getBoundingClientRect(),s=Math.abs(t?e.right-n:e.left-n);s<i&&(i=s,r=a)}if(r===this.activeIndexValue)return;this.activeIndexValue=r;let o=e[r];for(let[t,n]of e.entries())n.active=t===r;this.dispatchEvent(new CustomEvent(a,{detail:{item:o,index:r},bubbles:!0,composed:!0}))}get leadingPadding(){return parseFloat(getComputedStyle(this).getPropertyValue(`--_leading-padding`))||16}};i([e({type:String,reflect:!0})],s.prototype,`variant`,void 0),i([e({type:Number,reflect:!0,attribute:`preferred-item-width`})],s.prototype,`preferredItemWidth`,void 0),i([t({selector:`mdc-carousel-item`,flatten:!0})],s.prototype,`assignedItems`,void 0);export{s as BaseCarousel}; //# sourceMappingURL=base-carousel.js.map