UNPKG

@decidables/decidables-elements

Version:

decidables-elements: Basic UI Web Components for the decidables project

216 lines (166 loc) 5.39 kB
import {ifDefined} from 'lit/directives/if-defined.js'; import {css, html} from 'lit'; import DecidablesElement from './decidables-element'; export default class DecidablesSpinner extends DecidablesElement { static get properties() { return { disabled: { attribute: 'disabled', type: Boolean, reflect: true, }, max: { attribute: 'max', type: Number, reflect: true, }, min: { attribute: 'min', type: Number, reflect: true, }, step: { attribute: 'step', type: Number, reflect: true, }, value: { attribute: 'value', type: Number, reflect: true, }, }; } constructor() { super(); // Attributes this.disabled = false; this.max = undefined; this.min = undefined; this.step = undefined; this.value = undefined; } inputted(event) { this.value = event.target.value; } static get styles() { return [ super.styles, css` :host { ---decidables-spinner-font-size: var(--decidables-spinner-font-size, 1.125rem); ---decidables-spinner-input-width: var(--decidables-spinner-input-width, 4rem); ---decidables-spinner-prefix: var(--decidables-spinner-prefix, ""); ---decidables-spinner-postfix: var(--decidables-spinner-postfix, ""); ---decidables-spinner-postfix-padding: var(--decidables-spinner-postfix-padding, 0rem); display: block; } label { position: relative; display: flex; flex-direction: column; align-items: center; margin: 0; font-size: 0.75rem; } label::before { position: absolute; bottom: 1px; left: calc(50% - var(---decidables-spinner-input-width) / 2 + 0.25rem); font-size: var(---decidables-spinner-font-size); line-height: normal; content: var(---decidables-spinner-prefix); } label::after { position: absolute; right: 0.25rem; bottom: 1px; font-size: var(---decidables-spinner-font-size); line-height: normal; content: var(---decidables-spinner-postfix); } input[type=number] { width: var(---decidables-spinner-input-width); padding: 1px var(---decidables-spinner-postfix-padding) 1px 2px; margin: 0; font-family: var(---font-family-base); font-size: var(---decidables-spinner-font-size); color: inherit; text-align: right; appearance: none; outline: none; background: none; border: 0; border-radius: 0; box-shadow: var(---shadow-2); } input[type=number]:hover { box-shadow: var(---shadow-4); } input[type=number]:focus, input[type=number]:active { box-shadow: var(---shadow-8); } input[type=number]:disabled { color: var(---color-text); border: 0; box-shadow: none; } /* HACK: Manage spinners in Firefox */ @supports (-moz-appearance: textfield) { input[type=number] { padding-right: calc(18px + var(---decidables-spinner-postfix-padding)); appearance: textfield; } /* HACK: Avoid elements shifting due to box-shadow! */ :host(.math) input[type=number]:hover { box-shadow: var(---shadow-2); } :host(.math) input[type=number]:focus, :host(.math) input[type=number]:active { box-shadow: var(---shadow-8); } input[type=number]:hover, input[type=number]:focus, input[type=number]:active { padding-right: var(---decidables-spinner-postfix-padding); appearance: none; } input[type=number]:disabled { padding-right: calc(18px + var(---decidables-spinner-postfix-padding)); appearance: textfield; } } /* HACK: Manage spinners in Chrome/Edge/Safari */ input[type=number]::-webkit-inner-spin-button { /* Avoid oversized spinners in Safari */ font-size: 1.125rem; opacity: 0; } input[type=number]:hover::-webkit-inner-spin-button, input[type=number]:focus::-webkit-inner-spin-button, input[type=number]:active::-webkit-inner-spin-button { opacity: 1; } input[type=number]:disabled::-webkit-inner-spin-button { opacity: 0; } /* HACK: Adjust padding on mobile w/o spinners */ @media only screen and (hover: none) and (pointer: coarse) { input[type=number] { padding-right: calc(1.125rem + var(---decidables-spinner-postfix-padding)); } } `, ]; } render() { return html` <label> <slot></slot> <input ?disabled=${this.disabled} type="number" min=${ifDefined(this.min)} max=${ifDefined(this.max)} step=${ifDefined(this.step)} .value=${this.value} @input=${this.inputted.bind(this)}> </label> `; } } customElements.define('decidables-spinner', DecidablesSpinner);