{"version":3,"sources":["components/number-input/number-input.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,EAAE,yBAAyB,EAAE,8BAA8B,EAAE,MAAM,QAAQ,CAAC;AAEnF,OAAO,OAAO,EAAE,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,yBAAyB,EAAE,8BAA8B,EAAE,CAAC;AAIrE;;;;;;GAMG;AAEH,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IAChD;;OAEG;IACH,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK;IAgBnC;;OAEG;IAEH,SAAS,CAAC,4BAA4B,CAAC,CAAC,EAAE,KAAK;IAe/C;;OAEG;IAEH,SAAS,CAAC,0BAA0B,CAAC,CAAC,EAAE,KAAK;IAe7C;;OAEG;IAEH,SAAS,CAAC,MAAM,EAAG,gBAAgB,CAAC;IAEpC,aAAa;IAUb,mBAAmB,CAAC,KAAK,EAAE,MAAM;IAWjC,SAAS,CAAC,IAAI,SAAM;IAEpB,SAAS,CAAC,IAAI,SAAM;IAEpB,SAAS,CAAC,KAAK,SAAO;IAEtB;;OAEG;IAEH,WAAW,4BAAqC;IAEhD;;OAEG;IACH,IACI,GAAG,WAEN;IAED,IAAI,GAAG,CAAC,KAAK,QAAA,EAIZ;IAED;;OAEG;IACH,IACI,GAAG,WAEN;IAED,IAAI,GAAG,CAAC,KAAK,QAAA,EAIZ;IAED;;OAEG;IACH,IACI,IAAI,WAEP;IAED,IAAI,IAAI,CAAC,KAAK,QAAA,EAIb;IAED;;OAEG;IAEH,MAAM,UAAS;IAEf;;OAEG;IAEH,4BAA4B,SAA2B;IAEvD;;OAEG;IAEH,4BAA4B,SAA2B;IAEvD;;OAEG;IAEH,IAAI,aAAsB;IAE1B;;;;OAIG;IAEH,kBAAkB,SAAM;IAExB;;;;OAIG;IAEH,kBAAkB,SAAM;IAExB;;OAEG;IACH,MAAM;IAIN;;OAEG;IACH,QAAQ;IAIR,gBAAgB;IAOhB,MAAM;IA6GN;;OAEG;IACH,MAAM,KAAK,UAAU,WAEpB;IAED,MAAM,CAAC,MAAM,MAAU;CACxB","file":"number-input.d.ts","sourcesContent":["/**\n * @license\n *\n * Copyright IBM Corp. 2019, 2021\n *\n * This source code is licensed under the Apache-2.0 license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { html, property, query, customElement } from 'lit-element';\nimport { classMap } from 'lit-html/directives/class-map';\nimport settings from 'carbon-components/es/globals/js/settings';\nimport WarningFilled16 from '@carbon/icons/lib/warning--filled/16';\nimport CaretUp16 from '@carbon/icons/lib/caret--up/16';\nimport CaretDown16 from '@carbon/icons/lib/caret--down/16';\nimport ifNonEmpty from '../../globals/directives/if-non-empty';\nimport { NUMBER_INPUT_COLOR_SCHEME, NUMBER_INPUT_VALIDATION_STATUS } from './defs';\nimport styles from './number-input.scss';\nimport BXInput, { INPUT_SIZE } from '../input/input';\n\nexport { NUMBER_INPUT_COLOR_SCHEME, NUMBER_INPUT_VALIDATION_STATUS };\n\nconst { prefix } = settings;\n\n/**\n * Number input.\n * @element bx-number-input\n * @slot helper-text - The helper text.\n * @slot label-text - The label text.\n * @slot validity-message - The validity message. If present and non-empty, this input shows the UI of its invalid state.\n */\n@customElement(`${prefix}-number-input`)\nexport default class BXNumberInput extends BXInput {\n  /**\n   * Handles `input` event on the `<input>` in the shadow DOM.\n   */\n  protected _handleInput(event: Event) {\n    const { target } = event;\n    const { value } = target as HTMLInputElement;\n    this.dispatchEvent(\n      new CustomEvent((this.constructor as typeof BXNumberInput).eventInput, {\n        bubbles: true,\n        composed: true,\n        cancelable: false,\n        detail: {\n          value,\n        },\n      })\n    );\n    super._handleInput(event);\n  }\n\n  /**\n   * Handles `click` event on the up button in the shadow DOM.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  protected _handleUserInitiatedStepDown(_: Event) {\n    const { _input: input } = this;\n    this.stepDown();\n    this.dispatchEvent(\n      new CustomEvent((this.constructor as typeof BXNumberInput).eventInput, {\n        bubbles: true,\n        composed: true,\n        cancelable: false,\n        detail: {\n          value: input.value,\n        },\n      })\n    );\n  }\n\n  /**\n   * Handles `click` event on the down button in the shadow DOM.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  protected _handleUserInitiatedStepUp(_: Event) {\n    const { _input: input } = this;\n    this.stepUp();\n    this.dispatchEvent(\n      new CustomEvent((this.constructor as typeof BXNumberInput).eventInput, {\n        bubbles: true,\n        composed: true,\n        cancelable: false,\n        detail: {\n          value: input.value,\n        },\n      })\n    );\n  }\n\n  /**\n   * The underlying input element\n   */\n  @query('input')\n  protected _input!: HTMLInputElement;\n\n  _testValidity() {\n    if (this._input?.valueAsNumber > Number(this.max)) {\n      return NUMBER_INPUT_VALIDATION_STATUS.EXCEEDED_MAXIMUM;\n    }\n    if (this._input?.valueAsNumber < Number(this.min)) {\n      return NUMBER_INPUT_VALIDATION_STATUS.EXCEEDED_MINIMUM;\n    }\n    return super._testValidity();\n  }\n\n  _getValidityMessage(state: string) {\n    if (Object.values(NUMBER_INPUT_VALIDATION_STATUS).includes(state as NUMBER_INPUT_VALIDATION_STATUS)) {\n      const stateMessageMap = {\n        [NUMBER_INPUT_VALIDATION_STATUS.EXCEEDED_MAXIMUM]: this.validityMessageMax,\n        [NUMBER_INPUT_VALIDATION_STATUS.EXCEEDED_MINIMUM]: this.validityMessageMin,\n      };\n      return stateMessageMap[state];\n    }\n    return super._getValidityMessage(state);\n  }\n\n  protected _min = '';\n\n  protected _max = '';\n\n  protected _step = '1';\n\n  /**\n   * The color scheme.\n   */\n  @property({ attribute: 'color-scheme', reflect: true })\n  colorScheme = NUMBER_INPUT_COLOR_SCHEME.REGULAR;\n\n  /**\n   * The minimum value allowed in the input\n   */\n  @property({ reflect: true })\n  get min() {\n    return this._min.toString();\n  }\n\n  set min(value) {\n    const oldValue = this.min;\n    this._min = value;\n    this.requestUpdate('min', oldValue);\n  }\n\n  /**\n   * The maximum value allowed in the input\n   */\n  @property({ reflect: true })\n  get max() {\n    return this._max.toString();\n  }\n\n  set max(value) {\n    const oldValue = this.max;\n    this._max = value;\n    this.requestUpdate('max', oldValue);\n  }\n\n  /**\n   * The amount the value should increase or decrease by\n   */\n  @property({ reflect: true })\n  get step() {\n    return this._step.toString();\n  }\n\n  set step(value) {\n    const oldValue = this.step;\n    this._step = value;\n    this.requestUpdate('step', oldValue);\n  }\n\n  /**\n   * Set to `true` to enable the mobile variant of the number input\n   */\n  @property({ type: Boolean, reflect: true })\n  mobile = false;\n\n  /**\n   * Aria text for the button that increments the value\n   */\n  @property({ attribute: 'increment-button-assistive-text' })\n  incrementButtonAssistiveText = 'increase number input';\n\n  /**\n   * Aria text for the button that decrements the value\n   */\n  @property({ attribute: 'decrement-button-assistive-text' })\n  decrementButtonAssistiveText = 'decrease number input';\n\n  /**\n   * The input box size.\n   */\n  @property({ reflect: true })\n  size = INPUT_SIZE.REGULAR;\n\n  /**\n   * The validity message shown when the value is greater than the maximum\n   *\n   * Also available via the `validity-message-max` slot\n   */\n  @property({ attribute: 'validity-message-max' })\n  validityMessageMax = '';\n\n  /**\n   * The validity message shown when the value is less than the minimum\n   *\n   * Also available via the `validity-message-min` slot\n   */\n  @property({ attribute: 'validity-message-min' })\n  validityMessageMin = '';\n\n  /**\n   * Handles incrementing the value in the input\n   */\n  stepUp() {\n    this._input.stepUp();\n  }\n\n  /**\n   * Handles decrementing the value in the input\n   */\n  stepDown() {\n    this._input.stepDown();\n  }\n\n  createRenderRoot() {\n    return this.attachShadow({\n      mode: 'open',\n      delegatesFocus: Number((/Safari\\/(\\d+)/.exec(navigator.userAgent) ?? ['', 0])[1]) <= 537,\n    });\n  }\n\n  render() {\n    const {\n      _handleInput: handleInput,\n      _handleUserInitiatedStepDown: handleUserInitiatedStepDown,\n      _handleUserInitiatedStepUp: handleUserInitiatedStepUp,\n    } = this;\n\n    const invalidIcon = WarningFilled16({ class: `${prefix}--number__invalid` });\n\n    const validity = this._testValidity();\n\n    const isGenericallyInvalid = () =>\n      this.invalid &&\n      validity !== NUMBER_INPUT_VALIDATION_STATUS.EXCEEDED_MAXIMUM &&\n      validity !== NUMBER_INPUT_VALIDATION_STATUS.EXCEEDED_MINIMUM;\n\n    const wrapperClasses = classMap({\n      [`${prefix}--number`]: true,\n      [`${prefix}--number--${this.colorScheme}`]: this.colorScheme,\n      [`${prefix}--number--mobile`]: this.mobile,\n      [`${prefix}--number--${this.size}`]: this.size,\n    });\n\n    const labelClasses = classMap({\n      [`${prefix}--label`]: true,\n      [`${prefix}--label--disabled`]: this.disabled,\n    });\n\n    const helperTextClasses = classMap({\n      [`${prefix}--form__helper-text`]: true,\n      [`${prefix}--form__helper-text--disabled`]: this.disabled,\n    });\n\n    const incrementButton = html`\n      <button\n        class=\"${prefix}--number__control-btn up-icon\"\n        aria-label=\"${this.incrementButtonAssistiveText}\"\n        aria-live=\"polite\"\n        aria-atomic=\"true\"\n        type=\"button\"\n        ?disabled=${this.disabled}\n        @click=${handleUserInitiatedStepUp}>\n        ${CaretUp16()}\n      </button>\n    `;\n    const decrementButton = html`\n      <button\n        class=\"${prefix}--number__control-btn down-icon\"\n        aria-label=\"${this.decrementButtonAssistiveText}\"\n        aria-live=\"polite\"\n        aria-atomic=\"true\"\n        type=\"button\"\n        ?disabled=${this.disabled}\n        @click=${handleUserInitiatedStepDown}>\n        ${CaretDown16()}\n      </button>\n    `;\n\n    const input = html`\n      <input\n        ?autocomplete=\"${this.autocomplete}\"\n        ?autofocus=\"${this.autofocus}\"\n        ?data-invalid=\"${this.invalid}\"\n        ?disabled=\"${this.disabled}\"\n        id=\"input\"\n        name=\"${ifNonEmpty(this.name)}\"\n        pattern=\"${ifNonEmpty(this.pattern)}\"\n        placeholder=\"${ifNonEmpty(this.placeholder)}\"\n        ?readonly=\"${this.readonly}\"\n        ?required=\"${this.required}\"\n        type=\"number\"\n        .value=\"${this._value}\"\n        @input=\"${handleInput}\"\n        min=\"${ifNonEmpty(this.min)}\"\n        max=\"${ifNonEmpty(this.max)}\"\n        step=\"${ifNonEmpty(this.step)}\"\n        role=\"alert\"\n        aria-atomic=\"true\" />\n    `;\n\n    const defaultLayout = html`\n      ${this.invalid ? invalidIcon : null} ${input}\n      <div class=\"${prefix}--number__controls\">${incrementButton} ${decrementButton}</div>\n    `;\n\n    const mobileLayout = html` ${decrementButton} ${input} ${incrementButton} `;\n\n    return html`\n      <div class=\"${wrapperClasses}\" ?data-invalid=${this.invalid}>\n        <label class=\"${labelClasses}\" for=\"input\">\n          <slot name=\"label-text\"> ${this.labelText} </slot>\n        </label>\n        <div class=\"${prefix}--number__input-wrapper\">${this.mobile ? mobileLayout : defaultLayout}</div>\n        <div class=\"${helperTextClasses}\">\n          <slot name=\"helper-text\"> ${this.helperText} </slot>\n        </div>\n        <div class=\"${prefix}--form-requirement\" ?hidden=\"${!isGenericallyInvalid()}\">\n          <slot name=\"validity-message\"> ${this.validityMessage} </slot>\n        </div>\n        <div class=\"${prefix}--form-requirement\" ?hidden=\"${validity !== NUMBER_INPUT_VALIDATION_STATUS.EXCEEDED_MAXIMUM}\">\n          <slot name=\"validity-message-max\"> ${this.validityMessageMax} </slot>\n        </div>\n        <div class=\"${prefix}--form-requirement\" ?hidden=\"${validity !== NUMBER_INPUT_VALIDATION_STATUS.EXCEEDED_MINIMUM}\">\n          <slot name=\"validity-message-min\"> ${this.validityMessageMin} </slot>\n        </div>\n      </div>\n    `;\n  }\n\n  /**\n   * The name of the custom event fired after the value is changed upon a user gesture.\n   */\n  static get eventInput() {\n    return `${prefix}-number-input`;\n  }\n\n  static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader\n}\n"]}