import{html as e,css as t}from"lit";import{classMap as i}from"lit/directives/class-map.js";import{ifDefined as r}from"lit/directives/if-defined.js";import{createRef as o,ref as s}from"lit/directives/ref.js";import{iconRemixEyeOffLine as n,iconRemixEyeLine as a}from"./assets/cc-remix.icons.js";import{C as l}from"./form-utils-4685920e.js";import{combineValidators as c,RequiredValidator as d,EmailValidator as p}from"./lib/form/validation.js";import{arrayEquals as u}from"./lib/utils.js";import{accessibilityStyles as h}from"./styles/accessibility.js";import{skeletonStyles as b}from"./styles/skeleton.js";import{i18n as g}from"./translation.js";import"./cc-clipboard.js";import"./cc-icon.js";import{CcInputEvent as m,CcRequestSubmitEvent as f}from"./components/common.events.js";import{CcTagsChangeEvent as v}from"./components/cc-input-text/cc-input-text.events.js";const y=" ";class w extends l{static get properties(){return{...super.properties,clipboard:{type:Boolean,reflect:!0},disabled:{type:Boolean,reflect:!0},hiddenLabel:{type:Boolean,attribute:"hidden-label"},inline:{type:Boolean,reflect:!0},label:{type:String},multi:{type:Boolean,reflect:!0},placeholder:{type:String},readonly:{type:Boolean,reflect:!0},required:{type:Boolean},resetValue:{type:String,attribute:"reset-value"},secret:{type:Boolean,reflect:!0},skeleton:{type:Boolean,reflect:!0},tags:{type:Array},type:{type:String,reflect:!0},value:{type:String},_showSecret:{type:Boolean,state:!0},_tagsEnabled:{type:Boolean,state:!0}}}static reactiveValidationProperties=["required","type"];constructor(){super(),this.clipboard=!1,this.disabled=!1,this.inline=!1,this.label=null,this.hiddenLabel=!1,this.multi=!1,this.placeholder="",this.readonly=!1,this.required=!1,this.resetValue="",this.secret=!1,this.skeleton=!1,this.tags=null,this.type="text",this.value="",this._errorRef=o(),this._inputRef=o(),this._showSecret=!1,this._tagsEnabled=!1,this._errorMessages={empty:()=>"email"===this.type?g("cc-input-text.error.empty.email"):g("cc-input-text.error.empty"),badEmail:()=>g("cc-input-text.error.bad-email")}}_getFormControlElement(){return this._inputRef.value}_getErrorElement(){return this._errorRef.value}_getErrorMessages(){return this._errorMessages}_getValidator(){return c([this.required?new d:null,"email"===this.type?new p:null])}_getFormControlData(){if(this._tagsEnabled){const e=new FormData;return this.tags.forEach((t=>{e.append(this.name,t)})),e}return this.value}_getReactiveValidationProperties(){return w.reactiveValidationProperties}get tags(){return this._tagsEnabled?this.value.split(y).filter((e=>""!==e)):null}set tags(e){if(this._tagsEnabled=null!=e,this._tagsEnabled){const t=this.tags;u(t,e)||(this.value=e.join(y),this.requestUpdate("tags",t))}}focus(){this._inputRef.value?.focus()}_onInput(e){if(this._tagsEnabled&&e.target.value.includes("\n")){const{selectionStart:t,selectionEnd:i}=e.target,r=e.target.value,o=e.target.value.replace(/\n/g,""),s=r.length-o.length;e.target.value=o,e.target.setSelectionRange(t-s,i-s)}this.value=e.target.value,this.dispatchEvent(new m(this.value)),this._tagsEnabled&&this.dispatchEvent(new v(this.tags))}_onFocus(e){this.readonly&&e.target.select()}_onClickSecret(){this._showSecret=!this._showSecret}_onKeyEvent(e){"keydown"!==e.type&&"keypress"!==e.type||e.stopPropagation(),this._tagsEnabled&&"keydown"===e.type&&"Enter"===e.key&&(e.preventDefault(),this._internals.form?.requestSubmit(),this.dispatchEvent(new f)),this.readonly||"keypress"!==e.type||"Enter"!==e.key||(!this.multi||this.multi&&(e.ctrlKey||e.metaKey))&&(this._internals.form?.requestSubmit(),this.dispatchEvent(new f))}render(){const t=this.value??"",o=t.split("\n").length,l=this.clipboard&&!this.disabled&&!this.skeleton,c=this.secret&&!this.multi&&!this.disabled&&!this.skeleton,d=this.multi||this._tagsEnabled,p=null!=this.errorMessage&&""!==this.errorMessage,u=t.split(y).map(((t,i,r)=>e`<span class="tag">${t}</span>${i!==r.length-1?y:""}`));return e`
      ${null!=this.label?e`
            <label class=${i({"visually-hidden":this.hiddenLabel})} for="input-id">
              <span class="label-text">${this.label}</span>
              ${this.required?e` <span class="required">${g("cc-input-text.required")}</span> `:""}
            </label>
          `:""}

      <div class="meta-input">
        <div
          class="wrapper ${i({skeleton:this.skeleton})}"
          @input=${this._onInput}
          @keydown=${this._onKeyEvent}
          @keypress=${this._onKeyEvent}
        >
          ${d?e`
                ${this._tagsEnabled&&!this.skeleton?e`
                      <!--
                We use this to display colored background rectangles behind space separated values.
                This needs to be on the same line and the 2 level parent is important to keep scroll behaviour.
              -->
                      <!-- prettier-ignore -->
                      <div class="input input-underlayer" style="--rows: ${o}"><div class="all-tags">${u}</div></div>
                    `:""}
                <textarea
                  id="input-id"
                  class="input ${i({"input-tags":this._tagsEnabled,error:p})}"
                  style="--rows: ${o}"
                  rows=${o}
                  ?disabled=${this.disabled||this.skeleton}
                  ?readonly=${this.readonly}
                  .value=${t}
                  placeholder=${this.placeholder}
                  spellcheck="false"
                  wrap="${r(this._tagsEnabled?"soft":void 0)}"
                  aria-describedby="help-id error-id"
                  @focus=${this._onFocus}
                  ${s(this._inputRef)}
                ></textarea>
              `:""}
          ${d?"":e`
                ${l&&this.readonly?e`
                      <!--
                This div has the same styles as the input (but it's hidden with height:0)
                this way we can use it to know what width the content is
                and "auto size" the container.
              -->
                      <div class="input input-mirror">${t}</div>
                    `:""}
                <input
                  id="input-id"
                  type=${this.secret&&!this._showSecret?"password":"text"}
                  class="input ${i({error:p})}"
                  ?disabled=${this.disabled||this.skeleton}
                  ?readonly=${this.readonly}
                  .value=${t}
                  placeholder=${this.placeholder}
                  spellcheck="false"
                  aria-describedby="help-id error-id"
                  @focus=${this._onFocus}
                  ${s(this._inputRef)}
                />
              `}

          <div class="ring"></div>
        </div>

        ${c?e`
              <button
                class="btn"
                @click=${this._onClickSecret}
                title=${this._showSecret?g("cc-input-text.secret.hide"):g("cc-input-text.secret.show")}
              >
                <cc-icon
                  class="btn-img"
                  .icon=${this._showSecret?n:a}
                  a11y-name=${this._showSecret?g("cc-input-text.secret.hide"):g("cc-input-text.secret.show")}
                  size="lg"
                ></cc-icon>
              </button>
            `:""}
        ${l?e` <cc-clipboard class="btn-copy" value="${this.value}"></cc-clipboard> `:""}
      </div>

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

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

        :host([multi]) {
          display: block;
        }

        /* region Common to cc-input-* & cc-select (apart from multi) */

        :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;
        }

        :host([inline][multi]) {
          display: grid;
        }

        .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;
          /* link to position:absolute of .ring */
          position: relative;
          vertical-align: top;
          width: 100%;
        }

        :host([multi]) .meta-input {
          display: flex;
        }

        .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;
          resize: none;
          width: 100%;
        }

        /* BASE */

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

        .input::placeholder {
          font-style: italic;
        }

        textarea:not([wrap]) {
          white-space: pre;
        }

        /* STATES */

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

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

        /* Hide only height and keep content width */

        .input-mirror {
          height: 0;
        }

        /* TAGS UNDERLAYER */

        .input-tags,
        .input-underlayer {
          font-family: var(--cc-input-font-family, var(--cc-ff-monospace));
          height: auto;
          padding: 0 3px;
          word-break: break-all;
          word-spacing: 0.5ch;
        }

        .input-underlayer {
          color: transparent;
          -moz-user-select: none;
          -webkit-user-select: none;
          -ms-user-select: none;
          user-select: none;
          white-space: pre-wrap;
          z-index: 1;
        }

        .input-underlayer .tag:not(:empty) {
          --color: var(--cc-color-bg-soft, #eee);

          background-color: var(--color);
          border-radius: 3px;
          box-shadow: 0 0 0 2px var(--color);
          padding: 1px 0;
        }

        /* 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.error + .ring {
          border-color: var(--cc-color-border-danger) !important;
        }

        .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: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, #eee);
        }

        :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, #eee);
          cursor: progress;
        }

        .skeleton .input,
        .skeleton .input::placeholder {
          color: transparent;
        }

        /* RESET */

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

        .btn,
        .btn-copy {
          flex-shrink: 0;
          margin: 0.2em 0.2em 0.2em 0;
          margin-right: 0.15em;
          z-index: 2;
        }

        .btn {
          border-radius: var(--cc-border-radius-small, 0.15em);
          cursor: pointer;
          height: 1.6em;
          width: 1.6em;
        }

        .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 {
          box-sizing: border-box;
          color: var(--cc-color-text-default, #000);
          padding: 15%;
        }
      `]}}window.customElements.define("cc-input-text",w);export{w as CcInputText};
//# sourceMappingURL=cc-input-text.js.map
