aria-progress-range-slider
Version:
Accessible progress bar / slider component
1 lines • 23.8 kB
Source Map (JSON)
{"version":3,"file":"aria-progress-range-slider.mjs","sources":["../src/helpers.ts","../src/index.ts"],"sourcesContent":["export function getElementLeft(el) {\n let left = 0;\n let element = el;\n\n // Loop through the DOM tree\n // and add it's parent's offset to get page offset\n do {\n left += element.offsetLeft || 0;\n element = element.offsetParent;\n } while (element);\n\n return left;\n}\n","import { getElementLeft } from './helpers';\n\n/*\n| | track\n|========= | progress\n| O | handle\n| [ X ] | value tooltip\n|--------------------------- | hover\n| [ Y ] | hover value tooltip\n|-------------------- | buffer\n*/\n\n// https://www.w3.org/TR/wai-aria-practices/examples/slider/slider-1.html\n\ntype TSelectorOrElement = HTMLElement | Element | string;\n\ninterface UIEvent {\n touches?: { pageX: number; }[];\n pageX?: number\n preventDefault():any\n}\n\ninterface IProgressBarOptions {\n ariaLabel: string\n ariaLabeledBy?: string,\n arrowMoveStep: number\n className: string\n disabled: boolean\n float: boolean\n getTooltipText(value:number, options?:IProgressBarOptions):string\n getValueText(value:number, options?:IProgressBarOptions):string\n initialValue: number\n max: number\n min: number\n onChange?(value:number, options?:IProgressBarOptions):any\n onDragEnd?(value:number, options?:IProgressBarOptions):any\n onDragMove?(value:number, options?:IProgressBarOptions):any\n onDragStart?(value:number, options?:IProgressBarOptions):any\n pageMoveStep: number,\n snap: boolean\n step: number\n}\n\ninterface IProgressBarOptionsPartial {\n ariaLabel?: string\n ariaLabeledBy?: string,\n arrowMoveStep?: number\n className?: string\n disabled?: boolean\n float?: boolean\n getTooltipText?(value:number, options?:IProgressBarOptions):string\n getValueText?(value:number, options?:IProgressBarOptions):string\n initialValue?: number\n max?: number\n min?: number\n onChange?(value:number, options?:IProgressBarOptions):any\n onDragEnd?(value:number, options?:IProgressBarOptions):any\n onDragMove?(value:number, options?:IProgressBarOptions):any\n onDragStart?(value:number, options?:IProgressBarOptions):any\n pageMoveStep?: number,\n snap?: boolean\n step?: number\n}\n\nconst DEFAULT_OPTIONS:IProgressBarOptions = {\n ariaLabel: 'Seek slider',\n arrowMoveStep: 1,\n pageMoveStep: 5,\n className: 'AriaProgressBar',\n disabled: false,\n float: false,\n getTooltipText: (value:number, options:IProgressBarOptions) => {\n if (options.float) {\n return value.toString();\n }\n\n return Math.round(value).toString();\n },\n getValueText: (value:number, options:IProgressBarOptions) => {\n // TODO think of a more friendly label\n return `${ value } ranging from ${ options.min } to ${ options.max }`\n },\n initialValue: 0,\n max: 100,\n min: 0,\n snap: true,\n step: 1,\n};\n\nconst keyCodes = {\n PAGE_UP: 33,\n PAGE_DOWN: 34,\n END: 35,\n HOME: 36,\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40,\n}\n\nclass ProgressBar {\n // HTML Elements\n private element:HTMLElement;\n private handleElement:HTMLElement;\n private trackElement:HTMLElement;\n private progressElement:HTMLElement;\n private bufferElement:HTMLElement;\n private hoverElement:HTMLElement;\n private valueTooltipElement:HTMLElement;\n private hoverTooltipElement:HTMLElement;\n\n private options:IProgressBarOptions;\n private value:number;\n private realValue:number;\n private range:number;\n private isDragging:boolean = false;\n private isMouseOver:boolean = false;\n private isDestroyed:boolean = false;\n\n private elementLeft:number;\n\n constructor(selectorOrElement:TSelectorOrElement, options:IProgressBarOptionsPartial) {\n if (typeof selectorOrElement === 'string') {\n this.element = document.querySelector(selectorOrElement);\n } else {\n this.element = selectorOrElement as HTMLElement;\n }\n\n if (!(this.element instanceof HTMLElement)) {\n throw('Given HTML element is not valid or doesn\\'t exist.')\n }\n\n this.options = {\n ...DEFAULT_OPTIONS,\n ...options,\n };\n\n this.range = this.options.max - this.options.min;\n\n this.createElements();\n\n if (this.options.disabled) {\n this.disable();\n }\n\n let value = 0;\n\n if (this.options.initialValue) {\n value = (this.options.initialValue - this.options.min) / this.range\n }\n\n this.updateValue(value);\n this.setAriaProps();\n\n\n // For IE only\n this.updateHoverTooltip(value);\n }\n\n // DOM\n\n private createElement(elementName:string, parentElement:HTMLElement) {\n const element = document.createElement('div');\n element.className = this.getClassName(elementName);\n\n parentElement.appendChild(element);\n\n return element;\n }\n\n private createElements() {\n this.trackElement = this.createElement('track', this.element);\n this.progressElement = this.createElement('progress', this.trackElement);\n this.hoverElement = this.createElement('hover', this.trackElement);\n this.bufferElement = this.createElement('buffer', this.trackElement);\n this.handleElement = this.createElement('handle', this.element);\n\n if (this.options.getTooltipText) {\n this.valueTooltipElement = this.createElement('mainTooltip', this.element);;\n this.hoverTooltipElement = this.createElement('hoverTooltip', this.element);\n }\n\n this.element.classList.add(this.options.className);\n\n this.element.setAttribute('tabindex', '0');\n this.element.setAttribute('role', 'slider');\n this.element.setAttribute('aria-valuemin', '0');\n\n this.setOptions();\n\n // Dragging\n // Touch events\n this.element.addEventListener('touchstart', this.handleDragStart);\n\n window.addEventListener('touchmove', this.handleTouchMove, {\n capture: false,\n passive: false,\n });\n window.addEventListener('touchend', this.handleDragEnd);\n\n // Dragging and hover\n // Mouse events\n this.element.addEventListener('mouseenter', this.handleMouseEnter);\n this.element.addEventListener('mouseleave', this.handleMouseLeave);\n this.element.addEventListener('mousedown', this.handleDragStart);\n\n window.addEventListener('mouseup', this.handleDragEnd);\n window.addEventListener('mousemove', this.handleMouseMove, false);\n\n // Keyboard events\n this.element.addEventListener('keydown', this.handleKeyDown);\n\n // TODO decide if mouse wheel support should be added\n }\n\n private getClassName(elementName:string, modifier:string = null) {\n if (modifier) {\n return `${ this.options.className }-${ elementName }--${ modifier }`;\n }\n\n return `${ this.options.className }-${ elementName }`;\n }\n\n // Event handlers\n\n private handleMouseEnter = () => {\n if (this.options.disabled) {\n return;\n }\n\n this.isMouseOver = true;\n this.elementLeft = getElementLeft(this.element);\n this.element.classList.add(`${ this.options.className }--hover`);\n }\n\n private handleMouseLeave = () => {\n this.isMouseOver = false;\n this.setHoverScale(0);\n this.element.classList.remove(`${ this.options.className }--hover`);\n }\n\n private handleDragStart = (e:UIEvent) => {\n if (this.options.disabled) {\n return;\n }\n\n this.isDragging = true;\n this.element.classList.add(`${ this.options.className }--dragging`);\n this.elementLeft = getElementLeft(this.element);\n\n const value = this.getValueFromEvent(e);\n this.updateValue(value);\n\n if (this.options.onDragStart) {\n this.options.onDragStart(this.realValue, this.options);\n }\n }\n\n private handleDragEnd = () => {\n if (this.isDragging) {\n if (this.options.onDragEnd) {\n this.options.onDragEnd(this.realValue, this.options);\n }\n\n if (this.options.onChange) {\n this.options.onChange(this.realValue, this.options);\n }\n }\n\n this.isDragging = false;\n this.element.classList.remove(`${ this.options.className }--dragging`);\n\n // TODO if need this for IE only\n // this.updateHoverTooltip(this.value);\n }\n\n private handleMouseMove = (e:UIEvent) => {\n if (!this.isDragging && !this.isMouseOver || this.options.disabled) {\n return;\n }\n\n const value = this.getValueFromEvent(e);\n\n this.updateHoverTooltip(value);\n\n if (this.isDragging) {\n this.handleDragMove(value);\n } else if (this.isMouseOver) {\n this.setHoverScale(value);\n }\n }\n\n private handleTouchMove = (e:UIEvent) => {\n if (!this.isDragging || this.options.disabled) {\n return;\n }\n\n e.preventDefault();\n\n const value = this.getValueFromEvent(e);\n\n this.handleDragMove(value);\n }\n\n private handleDragMove(value:number) {\n const previousRealValue = this.realValue;\n this.updateValue(value);\n\n if (previousRealValue !== this.realValue && this.options.onDragMove) {\n this.options.onDragMove(this.realValue, this.options);\n }\n }\n\n private handleKeyDown = (e:KeyboardEvent) => {\n if (this.options.disabled) {\n return;\n }\n\n const stepArrow = this.options.arrowMoveStep / this.range;\n const stepPage = this.options.pageMoveStep / this.range;\n\n /*\n Up and Right arrows increase slider value for \"arrowMoveStep\" (default 1)\n Down and Left arrows decrease slider value for \"arrowMoveStep\" (default 1)\n Page Up\tincreases slider value for \"pageMoveStep\" (default 10)\n Page Down\tdecreases slider value for \"pageMoveStep\" (default 10)\n Home sets slider to its minimum value.\n End\tsets slider to its maximum value.\n */\n const stepMap = {\n [keyCodes.HOME]: -1,\n [keyCodes.END]: 1,\n [keyCodes.PAGE_DOWN]: -stepPage,\n [keyCodes.PAGE_UP]: stepPage,\n [keyCodes.DOWN]: -stepArrow,\n [keyCodes.LEFT]: -stepArrow,\n [keyCodes.UP]: stepArrow,\n [keyCodes.RIGHT]: stepArrow,\n }\n\n const step = stepMap[e.keyCode];\n\n if (typeof step === 'number') {\n const previousRealValue = this.getRealValue();\n\n this.updateValue(this.includeStep(this.value + step));\n\n if (previousRealValue !== this.realValue && this.options.onChange) { // TODO\n this.options.onChange(this.realValue, this.options);\n }\n }\n }\n\n private getValueFromEvent(e:UIEvent) {\n const elementWidth = this.element.offsetWidth;\n let x;\n\n if (e.touches && e.touches.length === 1) {\n x = e.touches[0].pageX - this.elementLeft;\n } else if (e.pageX) {\n x = e.pageX - this.elementLeft;\n } else {\n return 0;\n }\n\n if (x < 0) {\n x = 0;\n } else if (x > elementWidth) {\n x = elementWidth;\n }\n\n return this.includeStep(x / elementWidth);\n }\n\n private setOptions() {\n this.element.setAttribute('aria-valuemax', this.options.max.toString());\n this.element.setAttribute('aria-label', this.options.ariaLabel);\n\n if (this.options.ariaLabeledBy) {\n this.element.setAttribute('aria-labeledby', this.options.ariaLabeledBy);\n }\n }\n\n private setAriaProps() {\n this.element.setAttribute('aria-valuenow', this.realValue.toString());\n this.element.setAttribute('aria-valuetext', this.options.getValueText(this.realValue, this.options))\n }\n\n private limitValue(value:number) {\n if (value < 0) {\n return 0;\n } else if (value > 1) {\n return 1;\n }\n\n return value;\n }\n\n private includeStep(value:number) {\n const step = this.options.step / this.range;\n\n if (this.options.snap) {\n value = Math.round(value / step) * step;\n value = value * this.range / this.range;\n }\n\n value = this.limitValue(value);\n\n return value;\n }\n\n private updateTooltip(value:number, realValue:number, element:HTMLElement) {\n if (this.options.getTooltipText) {\n element.style.left = `${ value * 100 }%`;\n element.innerHTML = this.options.getTooltipText(realValue, this.options);\n }\n }\n\n private updateValueTooltip(value:number) {\n this.updateTooltip(value, this.realValue, this.valueTooltipElement);\n }\n\n private updateHoverTooltip(value:number) {\n const hoverValue = value * this.range + this.options.min;\n\n this.updateTooltip(value, parseFloat(hoverValue.toFixed(4)), this.hoverTooltipElement);\n }\n\n private updateValue(value:number) {\n this.handleElement.style.left = `${ value * 100 }%`;\n this.progressElement.style.transform = `scaleX(${ value })`;\n\n if (this.value !== value || typeof value === 'undefined') {\n const previousRealValue = this.getRealValue();\n\n this.value = value;\n this.realValue = this.getRealValue();\n\n if (this.realValue !== previousRealValue) {\n this.setAriaProps();\n this.updateValueTooltip(value);\n }\n\n if (this.isDragging) {\n this.setHoverScale(0);\n }\n }\n }\n\n private setHoverScale(value:number) {\n this.hoverElement.style.transform = `scaleX(${ value })`;\n }\n\n private getRealValue() {\n const value = this.value * this.range + this.options.min;\n\n return parseFloat(value.toFixed(4));\n }\n\n private unbind() {\n // Touch events\n this.element.removeEventListener('touchstart', this.handleDragStart);\n\n window.removeEventListener('touchmove', this.handleTouchMove);\n window.removeEventListener('touchend', this.handleDragEnd);\n\n // Dragging and hover\n // Mouse events\n this.element.removeEventListener('mouseenter', this.handleMouseEnter);\n this.element.removeEventListener('mouseleave', this.handleMouseLeave);\n this.element.removeEventListener('mousedown', this.handleDragStart);\n\n window.removeEventListener('mouseup', this.handleDragEnd);\n window.removeEventListener('mousemove', this.handleMouseMove);\n\n // Keyboard events\n this.element.removeEventListener('keydown', this.handleKeyDown);\n }\n\n // Public\n public getValue() {\n if (this.isDestroyed) {\n console.warn('ProgressBar instance is destroyed, options: ', this.options);\n return;\n }\n\n return this.realValue;\n }\n\n public setValue(value:number) {\n if (this.isDestroyed) {\n console.warn('ProgressBar instance is destroyed, options: ', this.options);\n return;\n }\n\n if (this.isDragging) {\n return;\n }\n\n this.updateValue(this.includeStep(value / this.range));\n }\n\n public setBufferValue(value:number) {\n if (this.isDestroyed) {\n console.warn('ProgressBar instance is destroyed, options: ', this.options);\n return;\n }\n\n this.bufferElement.style.transform = `scaleX(${ value / this.range })`;\n }\n\n public disable() {\n if (this.isDestroyed) {\n console.warn('ProgressBar instance is destroyed, options: ', this.options);\n return;\n }\n\n this.options.disabled = true;\n this.element.classList.add(`${ this.options.className }--disabled`);\n this.element.setAttribute('aria-disabled', 'true');\n this.element.setAttribute('disabled', 'true');\n this.element.setAttribute('tabindex', '-1');\n }\n\n public enable() {\n if (this.isDestroyed) {\n console.warn('ProgressBar instance is destroyed, options: ', this.options);\n return;\n }\n\n this.options.disabled = false;\n this.element.classList.remove(`${ this.options.className }--disabled`);\n this.element.setAttribute('tabindex', '0');\n }\n\n public destroy() {\n if (this.isDestroyed) {\n console.warn('ProgressBar instance is already destroyed');\n return;\n }\n\n // Unbind everything\n this.unbind();\n\n // Empty element\n this.element.innerHTML = '';\n\n\n this.isDestroyed = true;\n\n this.element.classList.remove(this.options.className);\n\n this.element.removeAttribute('tabindex');\n this.element.removeAttribute('role');\n this.element.removeAttribute('aria-valuemin');\n this.element.removeAttribute('aria-valuemax');\n this.element.removeAttribute('aria-label');\n this.element.removeAttribute('aria-valuenow');\n this.element.removeAttribute('aria-valuetext');\n\n if (this.options.ariaLabeledBy) {\n this.element.removeAttribute('aria-labeledby');\n }\n }\n}\n\nexport default ProgressBar;\n\n"],"names":["getElementLeft","el","left","element","offsetLeft","offsetParent","DEFAULT_OPTIONS","ariaLabel","arrowMoveStep","pageMoveStep","className","disabled","float","getTooltipText","value","options","toString","Math","round","getValueText","initialValue","max","min","snap","step","ProgressBar","constructor","selectorOrElement","this","isMouseOver","elementLeft","classList","add","setHoverScale","remove","e","isDragging","getValueFromEvent","updateValue","onDragStart","realValue","onDragEnd","onChange","updateHoverTooltip","handleDragMove","preventDefault","stepArrow","range","stepPage","stepMap","keyCode","previousRealValue","getRealValue","includeStep","document","querySelector","HTMLElement","Object","createElements","disable","setAriaProps","createElement","elementName","parentElement","getClassName","appendChild","trackElement","progressElement","hoverElement","bufferElement","handleElement","valueTooltipElement","hoverTooltipElement","setAttribute","setOptions","addEventListener","handleDragStart","handleTouchMove","handleDragEnd","handleMouseEnter","handleMouseLeave","window","handleMouseMove","handleKeyDown","modifier","onDragMove","x","elementWidth","offsetWidth","touches","length","pageX","ariaLabeledBy","limitValue","updateTooltip","style","innerHTML","updateValueTooltip","parseFloat","toFixed","transform","unbind","removeEventListener","getValue","isDestroyed","warn","setValue","setBufferValue","enable","destroy","console","removeAttribute"],"mappings":"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"}