import{html as e,css as t}from"lit";import{classMap as r}from"lit/directives/class-map.js";import{createRef as i,ref as n}from"lit/directives/ref.js";import{iconRemixSubtractLine as o,iconRemixAddLine as a}from"./assets/cc-remix.icons.js";import{C as s}from"./form-utils-4685920e.js";import{combineValidators as l,RequiredValidator as c,NumberValidator as u}from"./lib/form/validation.js";import{accessibilityStyles as d}from"./styles/accessibility.js";import{skeletonStyles as p}from"./styles/skeleton.js";import{i18n as b}from"./translation.js";import"./cc-icon.js";import{CcInputEvent as m,CcRequestSubmitEvent as h}from"./components/common.events.js";class f extends s{static get properties(){return{...super.properties,controls:{type:Boolean},disabled:{type:Boolean,reflect:!0},hiddenLabel:{type:Boolean,attribute:"hidden-label"},inline:{type:Boolean,reflect:!0},label:{type:String},max:{type:Number},min:{type:Number},readonly:{type:Boolean,reflect:!0},required:{type:Boolean},resetValue:{type:Number,attribute:"reset-value"},skeleton:{type:Boolean,reflect:!0},step:{type:Number},value:{type:Number}}}static reactiveValidationProperties=["required","min","max"];constructor(){super(),this.controls=!1,this.disabled=!1,this.inline=!1,this.label=null,this.hiddenLabel=!1,this.max=null,this.min=null,this.readonly=!1,this.required=!1,this.resetValue=null,this.skeleton=!1,this.step=null,this.value=null,this._errorRef=i(),this._inputRef=i(),this._errorMessages={empty:()=>b("cc-input-number.error.empty"),badType:()=>b("cc-input-number.error.bad-type"),rangeUnderflow:()=>b("cc-input-number.error.range-underflow",{min:this.min}),rangeOverflow:()=>b("cc-input-number.error.range-overflow",{max:this.max})}}focus(){this._inputRef.value.focus()}_getFormControlElement(){return this._inputRef.value}_getErrorElement(){return this._errorRef.value}_getErrorMessages(){return this._errorMessages}_getValidator(){return l([this.required?new c:null,new u({min:this.min,max:this.max})])}_getFormControlData(){return this._inputRef.value.value}_getReactiveValidationProperties(){return f.reactiveValidationProperties}_onInput(e){this.value=e.target.valueAsNumber,this.dispatchEvent(new m(this.value))}_onFocus(e){this.readonly&&e.target.select()}_onKeyEvent(e){"keydown"!==e.type&&"keypress"!==e.type||e.stopPropagation(),"keydown"===e.type&&"Enter"===e.key&&(e.preventDefault(),this._internals.form?.requestSubmit(),this.dispatchEvent(new h)),this.readonly||"keypress"!==e.type||"Enter"!==e.key||(this._internals.form?.requestSubmit(),this.dispatchEvent(new h))}_onDecrement(){this._inputRef.value.stepDown(),this.value=this._inputRef.value.valueAsNumber,this.dispatchEvent(new m(this.value))}_onIncrement(){this._inputRef.value.stepUp(),this.value=this._inputRef.value.valueAsNumber,this.dispatchEvent(new m(this.value))}render(){const t=null!=this.value?this.value:0,i=this.controls&&!this.skeleton,s=this.value<=this.min&&null!=this.min,l=this.value>=this.max&&null!=this.max,c=null!=this.errorMessage&&""!==this.errorMessage;return e`
      ${null!=this.label?e`
            <label class=${r({"visually-hidden":this.hiddenLabel})} for="input-id">
              <span class="label-text">${this.label}</span>
              ${this.required?e` <span class="required">${b("cc-input-number.required")}</span> `:""}
            </label>
          `:""}

      <div class="meta-input">
        ${i?e`
              <button
                class="btn"
                @click=${this._onDecrement}
                ?disabled=${this.disabled||this.readonly||s}
              >
                <cc-icon
                  class="btn-img"
                  .icon=${o}
                  a11y-name="${b("cc-input-number.decrease")}"
                  size="lg"
                ></cc-icon>
              </button>
            `:""}
        <div class="wrapper ${r({skeleton:this.skeleton})}">
          <input
            id="input-id"
            type="number"
            class="input ${r({error:c})}"
            ?disabled=${this.disabled||this.skeleton}
            ?readonly=${this.readonly}
            min=${this.min??""}
            max=${this.max??""}
            step=${this.step??""}
            .value=${t}
            spellcheck="false"
            aria-describedby="help-id error-id"
            @focus=${this._onFocus}
            @input=${this._onInput}
            @keydown=${this._onKeyEvent}
            @keypress=${this._onKeyEvent}
            ${n(this._inputRef)}
          />
          <div class="ring"></div>
        </div>
        ${i?e`
              <button
                class="btn"
                @click=${this._onIncrement}
                ?disabled=${this.disabled||this.readonly||l}
              >
                <cc-icon
                  class="btn-img"
                  .icon=${a}
                  a11y-name="${b("cc-input-number.increase")}"
                  size="lg"
                ></cc-icon>
              </button>
            `:""}
      </div>

      <div class="help-container" id="help-id">
        <slot name="help"></slot>
      </div>

      ${c?e` <p class="error-container" id="error-id" ${n(this._errorRef)}>${this.errorMessage}</p>`:""}
    `}static get styles(){return[d,p,t`
        /* stylelint-disable no-duplicate-selectors */
        :host {
          display: inline-block;
        }

        /* region Common to cc-input-* & cc-select */

        :host([inline]) {
          align-items: baseline;
          display: inline-grid;
          gap: 0 var(--cc-form-label-gap-inline, 0.75em);
          grid-auto-rows: min-content;
          grid-template-areas:
            'label input'
            'label help'
            'label error';
          grid-template-columns: auto 1fr;
        }

        .help-container {
          grid-area: help;
        }

        .error-container {
          grid-area: error;
        }

        label {
          align-items: flex-end;
          cursor: pointer;
          display: flex;
          gap: 2em;
          justify-content: space-between;
          line-height: 1.25em;
          padding-block-end: var(--cc-form-label-gap, 0.35em);
        }

        label .label-text {
          color: var(--cc-input-label-color, inherit);
          font-size: var(--cc-input-label-font-size, inherit);
          font-weight: var(--cc-input-label-font-weight, normal);
        }

        :host([inline]) label {
          flex-direction: column;
          gap: 0;
          grid-area: label;
          line-height: normal;
          padding: 0;
        }

        .required {
          color: var(--cc-color-text-weak);
          font-size: 0.9em;
          font-variant: small-caps;
        }

        :host([inline]) .required {
          font-size: 0.8em;
        }

        slot[name='help']::slotted(*) {
          color: var(--cc-color-text-weak);
          font-size: 0.9em;
          margin: 0.3em 0 0;
        }

        .error-container {
          color: var(--cc-color-text-danger);
          margin: 0.5em 0 0;
        }
        /* endregion */

        .meta-input {
          box-sizing: border-box;
          display: inline-flex;
          grid-area: input;
          height: max-content;
          overflow: visible;
          /* link to position:absolute of .ring */
          position: relative;
          vertical-align: top;
          width: 100%;
        }

        .wrapper {
          display: grid;
          flex: 1 1 0;
          min-width: 0;
          overflow: hidden;
          /* see input to know why 0.15em */
          padding: 0.15em 0.5em;
        }

        /* RESET */

        input {
          /* remove Safari box shadow */
          -webkit-appearance: none;
          background: none;
          border: 1px solid #000;
          box-sizing: border-box;
          color: inherit;
          display: block;
          font-family: inherit;
          font-size: unset;
          margin: 0;
          padding: 0;
          width: 100%;
        }

        /* remove spinner firefox */

        input[type='number'] {
          -moz-appearance: textfield;
        }

        /* remove spinner safari */

        input[type='number']::-webkit-inner-spin-button,
        input[type='number']::-webkit-outer-spin-button {
          -webkit-appearance: none;
          margin: 0;
        }

        /* BASE */

        input {
          border: none;
          font-family: var(--cc-input-font-family, inherit);
          font-size: 0.85em;
          grid-area: 1 / 1 / 2 / 2;
          /* 2em with a 0.85em font-size ~ 1.7em */
          /* (2em - 1.7em) / 2 ~ 0.15em of padding (top and bottom) on the wrapper */
          height: 2em;
          line-height: 2em;
          overflow: hidden;
          text-align: var(--cc-input-number-align, left);
          z-index: 2;
        }

        /* STATES */

        input:focus,
        input:active {
          outline: 0;
        }

        input[disabled] {
          color: var(--cc-color-text-weak);
          opacity: 1;
          pointer-events: none;
        }

        button[disabled] {
          opacity: var(--cc-opacity-when-disabled);
          pointer-events: none;
        }

        /* We use this empty .ring element to decorate the input with background, border, box-shadows... */

        .ring {
          background: var(--cc-color-bg-default, #fff);
          border: 1px solid var(--cc-color-border-neutral-strong, #aaa);
          border-radius: var(--cc-border-radius-default, 0.25em);
          bottom: 0;
          box-shadow: 0 0 0 0 rgb(255 255 255 / 0%);
          left: 0;
          overflow: hidden;
          position: absolute;
          right: 0;
          top: 0;
          z-index: 0;
        }

        input:focus + .ring {
          border-color: var(--cc-color-border-neutral-focused, #777);
          outline: var(--cc-focus-outline, #000 solid 2px);
          outline-offset: var(--cc-focus-outline-offset, 2px);
        }

        input.error + .ring {
          border-color: var(--cc-color-border-danger) !important;
        }

        input.error:focus + .ring {
          outline: var(--cc-focus-outline-error, #000 solid 2px);
          outline-offset: var(--cc-focus-outline-offset, 2px);
        }

        input:hover + .ring {
          border-color: var(--cc-color-border-neutral-hovered, #777);
        }

        :host([disabled]) .ring {
          background: var(--cc-color-bg-neutral-disabled);
          border-color: var(--cc-color-border-neutral-disabled, #777);
        }

        :host([readonly]) .ring {
          background: var(--cc-color-bg-neutral-readonly, #aaa);
        }

        /* SKELETON */

        .skeleton .ring,
        .skeleton:hover .ring,
        .skeleton input:hover + .ring {
          background-color: var(--cc-color-bg-neutral-disabled);
          border-color: var(--cc-color-border-neutral-disabled, #777);
          cursor: progress;
        }

        .skeleton input {
          color: transparent;
        }

        /* RESET */

        .btn {
          background: transparent;
          border: none;
          display: block;
          font-family: inherit;
          font-size: unset;
          margin: 0;
          padding: 0;
        }

        .btn {
          border-radius: var(--cc-border-radius-small, 0.15em);
          cursor: pointer;
          flex-shrink: 0;
          height: 1.6em;
          margin: 0.2em;
          width: 1.6em;
          z-index: 2;
        }

        .btn:focus {
          outline: var(--cc-focus-outline, #000 solid 2px);
          outline-offset: var(--cc-focus-outline-offset, 2px);
        }

        .btn:active,
        .btn:hover {
          box-shadow: none;
          outline: 0;
        }

        .btn:hover {
          background-color: var(--cc-color-bg-neutral-hovered);
        }

        .btn:active {
          background-color: var(--cc-color-bg-neutral-active);
        }

        /* We can do this because we set a visible focus state */

        .btn::-moz-focus-inner {
          border: 0;
        }

        .btn-img {
          --cc-icon-color: var(--cc-input-btn-icons-color, #595959);

          box-sizing: border-box;
          padding: 15%;
        }

        .btn-img:hover {
          --cc-icon-color: var(--cc-color-text-primary);
        }
      `]}}window.customElements.define("cc-input-number",f);export{f as CcInputNumber};
//# sourceMappingURL=cc-input-number.js.map
