{"version":3,"file":"styles.css","mappings":"AAwPA,gBACA,kBACA,4BACA,CAEA,gBAaA,iBACA,SAVA,sBAKA,wCADA,YAGA,sBADA,eAJA,YAMA,qBAMA,oBAHA,UARA,kBANA,kBAEA,QADA,MAGA,UAcA,CAEA,gBAGA,aADA,aAEA,oBAHA,iBAIA,CAEA,gBAGA,mBAWA,iBACA,uDACA,2DAXA,sBAaA,eAjBA,aACA,cAUA,oBADA,eADA,oBAFA,YAJA,uBAGA,YAUA,aARA,UAIA,kBAPA,UA8BA,CAhBA,+BACA,sDACA,CAEA,+BACA,gDACA,CAEA,+BACA,kDACA,CAEA,+BACA,uDACA,UACA,CAGA,gBACA,mCACA,CAEA,0BACA,OAEA,2BACA,CAEA,QAEA,0BACA,CAEA,IACA,0BACA,CAEA,IACA,yBACA,CAEA,MAEA,uBACA,CACA","sources":["webpack://@square/maker/./src/components/PinInput/src/PinInputControl.vue"],"sourcesContent":["<template>\n\t<div\n\t\t:class=\"$s.PinInputContainer\"\n\t\t:style=\"computedStyles\"\n\t>\n\t\t<input\n\t\t\tref=\"input\"\n\t\t\t:class=\"$s.PinInput\"\n\t\t\t:maxlength=\"pinLength\"\n\t\t\t:value=\"inputValue\"\n\t\t\ttype=\"text\"\n\t\t\tinputmode=\"numeric\"\n\t\t\tpattern=\"[0-9]*\"\n\t\t\t:disabled=\"disabled || isShaking\"\n\t\t\t@keydown=\"handleKeyDown\"\n\t\t\t@keypress=\"sanitizePinInput\"\n\t\t\t@input=\"onInputPin\"\n\t\t\t@keyup=\"updateCaretPosition\"\n\t\t\t@click=\"updateCaretPosition\"\n\t\t\t@focus=\"setFocus(true)\"\n\t\t\t@blur=\"setFocus(false)\"\n\t\t>\n\t\t<div\n\t\t\t:class=\"{\n\t\t\t\t[$s.PinInputCells]: true,\n\t\t\t\t[$s.isShaking]: isShaking,\n\t\t\t}\"\n\t\t>\n\t\t\t<div\n\t\t\t\tv-for=\"pinPosition in pinLength\"\n\t\t\t\t:key=\"pinPosition\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t[$s.PinInputCell]: true,\n\t\t\t\t\t[$s.isFocused]: isCellFocused(pinPosition - 1),\n\t\t\t\t\t[$s.fill]: variant === 'fill',\n\t\t\t\t\t[$s.error]: invalid,\n\t\t\t\t\t[$s.disabled]: disabled || isShaking\n\t\t\t\t}\"\n\t\t\t>\n\t\t\t\t{{ inputValue[pinPosition - 1] }}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nconst INPUT_FILTER_REGEX = /\\D/gimu;\nconst INPUT_KEY_REGEX = /\\d/;\n\nconst DEFAULT_INPUT_SIZE = 6;\nconst PIN_CELL_WIDTH = 50;\nconst PIN_CELL_SPACING = 8;\nconst ONE = 1;\nconst SHAKE_TIMEOUT = 1000;\n\nexport default {\n\tprops: {\n\t\t/**\n\t\t * Length of pin\n\t\t */\n\t\tpinLength: {\n\t\t\ttype: Number,\n\t\t\tdefault: DEFAULT_INPUT_SIZE,\n\t\t\tvalidator: (value) => value > 0,\n\t\t},\n\n\t\t/**\n\t\t * Input variant\n\t\t */\n\t\tvariant: {\n\t\t\ttype: String,\n\t\t\tdefault: 'fill',\n\t\t\tvalidator: (variant) => ['fill', 'outline'].includes(variant),\n\t\t},\n\n\t\t/**\n\t\t * Toggles input invalid state\n\t\t */\n\t\tinvalid: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/**\n\t\t * Disable the inputs\n\t\t */\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tinputValue: '',\n\t\t\tisFocused: false,\n\t\t\tcaretPosition: undefined,\n\t\t\tshakeTimeout: undefined,\n\t\t\tisShaking: false,\n\t\t};\n\t},\n\n\tcomputed: {\n\t\tcomputedStyles() {\n\t\t\tconst pinInputWidth = (this.pinLength * PIN_CELL_WIDTH)\n\t\t\t\t+ ((this.pinLength - ONE) * PIN_CELL_SPACING);\n\t\t\tconst caretColor = this.shouldShowCaret\n\t\t\t\t? 'var(--maker-color-body, #000000)'\n\t\t\t\t: 'transparent';\n\n\t\t\treturn {\n\t\t\t\t'--pin-input-width': `${pinInputWidth}px`,\n\t\t\t\t'--pin-cell-caret-color': caretColor,\n\t\t\t};\n\t\t},\n\n\t\tshouldShowCaret() {\n\t\t\tif (!this.isFocused) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn this.caretPosition === this.inputValue.length && this.caretPosition !== this.pinLength;\n\t\t},\n\t},\n\n\twatch: {\n\t\t// Refocus on first input when re-enabled\n\t\tdisabled(isDisabled) {\n\t\t\tif (!isDisabled) {\n\t\t\t\tthis.$refs.input.focus();\n\t\t\t}\n\t\t},\n\t},\n\n\tbeforeDestroy() {\n\t\tclearTimeout(this.shakeTimeout);\n\t},\n\n\tmethods: {\n\t\tsetFocus(focusState) {\n\t\t\tthis.isFocused = focusState;\n\t\t\tif (this.isFocused) {\n\t\t\t\tthis.$nextTick(() => this.setCaretPositionToEnd());\n\t\t\t}\n\t\t},\n\n\t\tisCellFocused(pinIndex) {\n\t\t\tconst isCurrentIndex = this.caretPosition === pinIndex;\n\t\t\tconst isLastIndex = this.pinLength === pinIndex + ONE;\n\t\t\tconst isActiveIndex = isLastIndex\n\t\t\t\t? isCurrentIndex || this.caretPosition === this.pinLength\n\t\t\t\t: isCurrentIndex;\n\n\t\t\tif (!this.isFocused) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn this.isFocused && isActiveIndex;\n\t\t},\n\n\t\tonInputPin(event) {\n\t\t\tconst input = event?.target?.value;\n\t\t\tthis.handlePinChange(input);\n\t\t},\n\n\t\thandlePinChange(input) {\n\t\t\tthis.updateCaretPosition();\n\t\t\tif (!input) {\n\t\t\t\tthis.inputValue = input ?? '';\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.inputValue = this.sanitizePinValue(input);\n\n\t\t\tif (this.inputValue.length === this.pinLength) {\n\t\t\t\tthis.handleComplete(this.inputValue);\n\t\t\t}\n\t\t},\n\n\t\thandleKeyDown(event) {\n\t\t\tif (event.key === 'Backspace') {\n\t\t\t\tthis.handleBackspace(event);\n\t\t\t}\n\t\t},\n\n\t\tsanitizePinValue(input = '') {\n\t\t\treturn input\n\t\t\t\t.replace(INPUT_FILTER_REGEX, '')\n\t\t\t\t.slice(0, this.pinLength);\n\t\t},\n\n\t\tsanitizePinInput(event) {\n\t\t\tif (!event.key?.match(INPUT_KEY_REGEX)) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tevent.stopPropagation();\n\t\t\t}\n\t\t},\n\n\t\tupdateCaretPosition() {\n\t\t\tthis.caretPosition = this.isFocused\n\t\t\t\t? this.$refs.input.selectionStart\n\t\t\t\t: undefined;\n\t\t},\n\n\t\tsetCaretPositionToEnd() {\n\t\t\tthis.caretPosition = this.inputValue.length;\n\t\t\tthis.$refs.input.selectionStart = this.caretPosition;\n\t\t\tthis.$refs.input.selectionEnd = this.caretPosition;\n\t\t},\n\n\t\thandleComplete(pin) {\n\t\t\tthis.$emit('complete', pin);\n\t\t},\n\n\t\thandleBackspace(event) {\n\t\t\tif (this.caretPosition < this.inputValue.length) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tevent.stopPropagation();\n\n\t\t\t\tconst position = this.caretPosition;\n\t\t\t\tthis.inputValue = this.inputValue.slice(0, position)\n\t\t\t\t\t+ this.inputValue.slice(position + ONE);\n\n\t\t\t\tthis.$nextTick(() => {\n\t\t\t\t\tthis.$refs.input.selectionStart = position;\n\t\t\t\t\tthis.$refs.input.selectionEnd = position;\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * shakes and clears pininput\n\t\t * @public\n\t\t */\n\t\tshakeAndClearInputs() {\n\t\t\tthis.inputValue = '';\n\t\t\tthis.isShaking = true;\n\t\t\tclearTimeout(this.shakeTimeout);\n\t\t\tthis.shakeTimeout = setTimeout(() => {\n\t\t\t\tthis.isShaking = false;\n\t\t\t\tthis.$refs.input.focus();\n\t\t\t}, SHAKE_TIMEOUT);\n\t\t},\n\t},\n};\n</script>\n\n<style module=\"$s\">\n.PinInputContainer {\n\tposition: relative;\n\twidth: var(--pin-input-width);\n}\n\n.PinInput {\n\tposition: absolute;\n\ttop: 0;\n\tright: 0;\n\tbox-sizing: border-box;\n\twidth: 100%;\n\theight: 100%;\n\tpadding-left: 25px;\n\tcolor: transparent;\n\tcaret-color: var(--pin-cell-caret-color);\n\tfont-size: 20px;\n\tfont-family: monospace;\n\tletter-spacing: 2.3em;\n\tbackground: transparent;\n\tborder: 0;\n\toutline: 0;\n\n\t/* This makes the input clickable but not actually visible */\n\topacity: 0 !important;\n}\n\n.PinInputCells {\n\tposition: relative;\n\tdisplay: flex;\n\tgap: 8px;\n\tpointer-events: none;\n}\n\n.PinInputCell {\n\tdisplay: flex;\n\tflex: 0 1 auto;\n\talign-items: center;\n\tjustify-content: center;\n\tbox-sizing: border-box;\n\twidth: 50px;\n\tmin-width: 0;\n\theight: 50px;\n\tpadding: 0;\n\tfont-weight: inherit;\n\tfont-size: 16px;\n\tfont-family: inherit;\n\ttext-align: center;\n\tbackground: transparent;\n\tborder: 1px solid $maker-color-neutral-20;\n\tborder-radius: $maker-shape-default-border-radius;\n\toutline: none;\n\tcursor: pointer;\n\n\t&.isFocused {\n\t\tborder: 2px solid $maker-color-neutral-80;\n\t}\n\n\t&.fill {\n\t\tbackground: $maker-color-neutral-10;\n\t}\n\n\t&.error {\n\t\tborder-color: $maker-color-error-fill;\n\t}\n\n\t&.disabled {\n\t\tborder: 1px solid $maker-color-neutral-20;\n\t\topacity: 0.9;\n\t}\n}\n\n.isShaking {\n\tanimation: invalidpinshake 500ms linear;\n}\n\n@keyframes invalidpinshake {\n\t8%,\n\t41% {\n\t\ttransform: translateX(-16px);\n\t}\n\n\t25%,\n\t58% {\n\t\ttransform: translateX(16px);\n\t}\n\n\t75% {\n\t\ttransform: translateX(-8px);\n\t}\n\n\t92% {\n\t\ttransform: translateX(8px);\n\t}\n\n\t0%,\n\t100% {\n\t\ttransform: translateX(0);\n\t}\n}\n</style>\n"],"names":[],"sourceRoot":""}