component ToggleCount { outputs { change(payload: { value?: string | number | boolean | null; values?: Array; sourceEvent?: Event; [key: string]: string | number | boolean | null | object } | string | number | boolean | null) toggle(payload: { sourceEvent?: Event; [key: string]: string | number | boolean | null | object }) } props { size: string = "default" color: string = "primary" variant: string = "segmented" class: string = "" name: string = "billing-cycle" value: string = "monthly" firstValue: string = "monthly" firstLabel: string = "Monthly" secondValue: string = "annual" secondLabel: string = "Annual" ariaLabel: string = "Billing frequency" items: unknown[] = [] currency: string = "$" suffix: string = "" firstValueKey: string = "monthly" secondValueKey: string = "annual" emptyValue: string = "—" align: string = "end" fullWidth: boolean = true disabled: boolean = false animate: boolean = true animationDuration: number = 450 animationSteps: number = 18 } state selectedValue = value functions { shared function isFirstSelected() { return selectedValue === firstValue } shared function isSecondSelected() { return selectedValue === secondValue } shared function displayValue(item) { if (isSecondSelected()) { return item[secondValueKey] !== undefined ? item[secondValueKey] : emptyValue } return item[firstValueKey] !== undefined ? item[firstValueKey] : emptyValue } client function dispatchToggleEvent(sourceEvent, previousValue, root, customEvent) { root = sourceEvent.currentTarget.closest("[data-wrn-toggle-count]") if (!root) { return } customEvent = document.createEvent("CustomEvent") customEvent.initCustomEvent("change", true, false, { component: "ToggleCount", name: name, value: selectedValue, previousValue: previousValue, firstValue: firstValue, secondValue: secondValue }) root.dispatchEvent(customEvent) customEvent = document.createEvent("CustomEvent") customEvent.initCustomEvent("toggle", true, false, { component: "ToggleCount", name: name, value: selectedValue, previousValue: previousValue, firstValue: firstValue, secondValue: secondValue }) root.dispatchEvent(customEvent) } client function selectValue(sourceEvent, nextValue, previousValue) { if (disabled || selectedValue === nextValue) { return } previousValue = selectedValue selectedValue = nextValue if ( animate && !window.matchMedia("(prefers-reduced-motion: reduce)").matches ) { animateDisplayedValues(sourceEvent, previousValue) } dispatchToggleEvent(sourceEvent, previousValue) } client function animateDisplayedValues(sourceEvent, previousValue, root, nodes, animationToken) { root = sourceEvent.currentTarget.closest("[data-wrn-toggle-count]") if (!root) { return } animationToken = String(Date.now()) + ":" + String(selectedValue) root.setAttribute("data-animation-token", animationToken) nodes = root.querySelectorAll("[data-toggle-count-value]") animateValueAt(nodes, 0, previousValue, root, animationToken) } client function animateValueAt( nodes, index, previousValue, root, animationToken, node, fromValue, toValue ) { if (index >= nodes.length) { return } node = nodes[index] fromValue = Number( previousValue === secondValue ? node.getAttribute("data-second-value") : node.getAttribute("data-first-value") ) toValue = Number( selectedValue === secondValue ? node.getAttribute("data-second-value") : node.getAttribute("data-first-value") ) if (!Number.isNaN(fromValue) && !Number.isNaN(toValue)) { node.replaceChildren(String(fromValue)) scheduleValueFrame( node, fromValue, toValue, 1, Math.max(1, Number(animationSteps) || 1), Math.max(1, Number(animationDuration) || 1), root, animationToken ) } animateValueAt( nodes, index + 1, previousValue, root, animationToken ) } client function scheduleValueFrame( node, fromValue, toValue, frame, totalFrames, duration, root, animationToken, nextValue ) { if (frame > totalFrames) { return } nextValue = Math.round( fromValue + (toValue - fromValue) * (frame / totalFrames) ) setTimeout( applyAnimatedValue, Math.max(1, duration * frame / totalFrames), node, nextValue, root, animationToken ) scheduleValueFrame( node, fromValue, toValue, frame + 1, totalFrames, duration, root, animationToken ) } client function applyAnimatedValue( node, nextValue, root, animationToken ) { if ( root && root.getAttribute("data-animation-token") !== animationToken ) { return } node.replaceChildren(String(nextValue)) } client function toggleValue(sourceEvent) { selectValue( sourceEvent, isFirstSelected() ? secondValue : firstValue ) } } view {
{#if variant === "switch"} {firstLabel} {secondLabel} {:else}
{/if}
{#if items.length > 0}
{#each items as item}
{item.label || item.name} {#if currency}{currency}{/if} {displayValue(item)} {#if suffix}{suffix}{/if} {#if item.description}{item.description}{/if}
{/each}
{/if}
} }