@sandlada/mdc
Version:
@sandlada/mdc is an open source component library that follows the Material Design 3 design specifications.
35 lines • 5.28 kB
JavaScript
import{customElement as e}from"../../node_modules/@lit/reactive-element/decorators/custom-element.js";import{property as t}from"../../node_modules/@lit/reactive-element/decorators/property.js";import"../../node_modules/lit/decorators.js";import{html as n,nothing as r}from"../../node_modules/lit-html/lit-html.js";import{LitElement as i}from"../../node_modules/lit-element/lit-element.js";import"../../node_modules/lit/index.js";import{classMap as a}from"../../node_modules/lit-html/directives/class-map.js";import"../../node_modules/lit/directives/class-map.js";import{composeMixin as o}from"../../utils/compose-mixin/compose-mixin.js";import s from"../../_virtual/_@oxc-project_runtime@0.144.0/helpers/esm/decorate.js";import{mixinDelegatesAria as c}from"../../utils/aria/delegate.js";import{styleMap as l}from"../../node_modules/lit-html/directives/style-map.js";import"../../node_modules/lit/directives/style-map.js";import{ExpressiveProgressIndicatorStyles as u}from"./expressive-progress-indicator.style.js";
/**
* @license
* Copyright 2026 Kai-Orion & Sandlada
* SPDX-License-Identifier: MIT
*
* @fileoverview
* `mdc-expressive-progress-indicator` — Material Design 3 Expressive progress
* indicator.
*
* Follows the MD3E spec as implemented by Flutter (year2024) and Jetpack
* Compose:
*
* **Linear**:
* - The active indicator and the track use round caps (pill-shaped) with a
* `secondaryContainer` track separated by a visual gap.
* - A round stop indicator (primary) sits at the trailing edge of the track
* while determinate.
* - Determinate resizes the active bar with a springy, non-overshooting
* settle approximating Compose's `SpringSpec(NoBouncy, VeryLow)`.
* - Indeterminate animates two bars with translateX + scaleX keyframes at
* Compose's `LinearAnimationDuration = 1750ms`.
*
* **Circular**:
* - Determinate draws a primary arc plus a `secondaryContainer` track arc,
* each with round stroke caps, separated by the same gap (Compose gap
* formula).
* - Indeterminate uses an SVG arc spinner rotating 1440deg over 6000ms while
* sweeping between 0.1 and 0.87 of the circle (Compose
* `CircularAnimationDuration` + `EasingStandardCubicBezier`).
*
* @link https://m3.material.io/components/progress-indicator/specs
*/
let d=class extends o(c)(i){constructor(...e){super(...e),this.variant=`linear`,this.value=0,this.max=1,this.indeterminate=!1,this.circularSize=`medium`}static{this.styles=u}static{this.shadowRootOptions={mode:`open`,delegatesFocus:!1}}firstUpdated(e){super.firstUpdated(e),this.setupAria()}render(){let{ariaLabel:e}=this,t=this.max>0?this.value/this.max:0;return n`<div class="progress ${a(this.getRenderClasses())}" style="--_fraction:${t}" role="progressbar" aria-label="${e||r}" aria-valuemin="0" aria-valuemax="${this.max}" aria-valuenow="${this.indeterminate?r:this.value}">${this.variant===`linear`?this.renderLinear():this.renderCircular()}</div>`}getRenderClasses(){return{indeterminate:this.indeterminate,linear:this.variant===`linear`,circular:this.variant===`circular`}}renderLinear(){return this.indeterminate?this.renderLinearIndeterminate():this.renderLinearDeterminate()}renderLinearDeterminate(){return n`<div class="track" aria-hidden="true"></div><div class="active-bar" aria-hidden="true"></div><div class="stop-indicator" aria-hidden="true"></div>`}renderLinearIndeterminate(){return n`<div class="track" aria-hidden="true"></div><div class="bar primary-bar"><div class="bar-inner"></div></div><div class="bar secondary-bar"><div class="bar-inner"></div></div>`}renderCircular(){return this.indeterminate?this.renderCircularIndeterminate():this.renderCircularDeterminate()}renderCircularDeterminate(){let e=this.max>0?this.value/this.max:0,{boxSize:t,strokeWidth:i,gap:a}=this.getCircularMetrics(),o=e*360,s=t>0?(a+i)/(Math.PI*t)*360:0,c=Math.min(o,s),u=360-o-2*c,d=100-o/360*100,f=u/360*100,p=(o+c)/360*100,m=f+100-p;return n`<svg viewBox="0 0 4800 4800" aria-hidden="true">${u>.001?n`<circle class="track-circle" pathLength="100" style="${l({strokeDasharray:`${f} 100`,strokeDashoffset:`${m}`})}"></circle>`:r}<circle class="active-circle" pathLength="100" stroke-dashoffset="${d}"></circle></svg>`}renderCircularIndeterminate(){return n`<div class="circular-spinner" aria-hidden="true"><svg viewBox="0 0 4800 4800"><circle class="spinner-arc" pathLength="100"></circle></svg></div>`}getCircularMetrics(){let e=getComputedStyle(this),t=parseFloat(e.getPropertyValue(`--_circular-${this.circularSize}-size`))||64,n=parseFloat(e.getPropertyValue(`--_circular-${this.circularSize}-stroke-width`))||4,r=parseFloat(e.getPropertyValue(`--_circular-track-gap`))||4;return{boxSize:t-8,strokeWidth:n,gap:r}}setupAria(){!this.getAttribute(`aria-label`)&&!this.getAttribute(`aria-labelledby`)&&this.setAttribute(`aria-label`,`Progress`)}};s([t({type:String,reflect:!0})],d.prototype,`variant`,void 0),s([t({type:Number})],d.prototype,`value`,void 0),s([t({type:Number})],d.prototype,`max`,void 0),s([t({type:Boolean,reflect:!0})],d.prototype,`indeterminate`,void 0),s([t({type:String,reflect:!0,attribute:`circular-size`})],d.prototype,`circularSize`,void 0),d=s([e(`mdc-expressive-progress-indicator`)],d);export{d as MDCExpressiveProgressIndicator};
//# sourceMappingURL=expressive-progress-indicator.js.map