{"version":3,"file":"textarea.vue2.mjs","sources":["../../../components/textarea/textarea.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { Icon } from '@/components/icon'\nimport { useFieldStore } from '@/components/form'\n\nimport { computed, ref, toRef, watch } from 'vue'\n\nimport {\n  createIconProp,\n  createStateProp,\n  emitEvent,\n  useIcons,\n  useLocale,\n  useNameHelper,\n  useProps\n} from '@vexip-ui/config'\nimport { debounce, isNull, throttle, toNumber } from '@vexip-ui/utils'\nimport { textareaProps } from './props'\n\ndefineOptions({ name: 'Textarea' })\n\nconst { idFor, state, labelId, disabled, loading, validateField, getFieldValue, setFieldValue } =\n  useFieldStore<string>(() => textarea.value?.focus())\n\nconst _props = defineProps(textareaProps)\nconst props = useProps('textarea', _props, {\n  state: createStateProp(state),\n  locale: null,\n  value: {\n    default: () => getFieldValue(),\n    static: true\n  },\n  placeholder: null,\n  rows: 2,\n  noResize: false,\n  autofocus: false,\n  spellcheck: false,\n  autocomplete: false,\n  readonly: false,\n  disabled: () => disabled.value,\n  debounce: false,\n  delay: null,\n  maxLength: 0,\n  loading: () => loading.value,\n  loadingIcon: createIconProp(),\n  loadingLock: false,\n  loadingEffect: null,\n  sync: false,\n  controlClass: null,\n  controlAttrs: null,\n  name: {\n    default: '',\n    static: true\n  }\n})\n\nconst emit = defineEmits(['update:value'])\n\nconst nh = useNameHelper('textarea')\nconst locale = useLocale('input', toRef(props, 'locale'))\nconst icons = useIcons()\n\nconst focused = ref(false)\nconst currentValue = ref(props.value)\nconst currentLength = ref(props.value ? props.value.length : 0)\nconst composing = ref(false)\n\nconst textarea = ref<HTMLTextAreaElement>()\n\nlet lastValue = props.value\n\nconst isReadonly = computed(() => {\n  return (props.loading && props.loadingLock) || props.readonly\n})\nconst className = computed(() => {\n  return {\n    [nh.b()]: true,\n    [nh.ns('input-vars')]: true,\n    [nh.bs('vars')]: true,\n    [nh.bm('inherit')]: props.inherit,\n    [nh.bm('focused')]: focused.value,\n    [nh.bm('disabled')]: props.disabled,\n    [nh.bm('readonly')]: isReadonly.value,\n    [nh.bm('loading')]: props.loading,\n    [nh.bm('no-resize')]: props.noResize,\n    [nh.bm(props.state)]: props.state !== 'default'\n  }\n})\nconst autoComplete = computed(() => {\n  return typeof props.autocomplete === 'boolean'\n    ? props.autocomplete\n      ? 'on'\n      : 'off'\n    : props.autocomplete\n})\n\nwatch(\n  () => props.value,\n  value => {\n    currentValue.value = value\n    lastValue = value\n    limitValueLength()\n  }\n)\n\ndefineExpose({\n  idFor,\n  currentValue,\n  currentLength,\n  composing,\n  isReadonly,\n  textarea,\n  copyValue,\n  focus: (options?: FocusOptions) => textarea.value?.focus(options),\n  blur: () => textarea.value?.blur()\n})\n\nfunction handleFocus(event: FocusEvent) {\n  focused.value = true\n  emitEvent(props.onFocus, event)\n}\n\nfunction handleBlur(event: FocusEvent) {\n  focused.value = false\n  emitEvent(props.onBlur, event)\n}\n\nfunction handleChange(event: Event) {\n  const type = event.type as 'change' | 'input'\n\n  if (composing.value) {\n    if (type === 'input') return\n\n    composing.value = false\n  }\n\n  currentValue.value = (event.target as HTMLTextAreaElement).value\n  limitValueLength()\n\n  if (type === 'change') {\n    if (lastValue === currentValue.value) return\n\n    lastValue = currentValue.value\n\n    if (!props.sync) {\n      emit('update:value', currentValue.value)\n      setFieldValue(currentValue.value)\n    }\n\n    emitEvent(props.onChange, currentValue.value)\n\n    if (!props.sync) {\n      validateField()\n    }\n  } else {\n    if (props.sync) {\n      emit('update:value', currentValue.value)\n      setFieldValue(currentValue.value)\n    }\n\n    emitEvent(props.onInput, currentValue.value)\n\n    if (props.sync) {\n      validateField()\n    }\n  }\n}\n\nfunction handleEnter() {\n  emitEvent(props.onEnter)\n}\n\nfunction handleKeyDown(event: KeyboardEvent) {\n  emitEvent(props.onKeyDown, event)\n}\n\nfunction handleKeyPress(event: KeyboardEvent) {\n  emitEvent(props.onKeyPress, event)\n}\n\nfunction handleKeyUp(event: KeyboardEvent) {\n  emitEvent(props.onKeyUp, event)\n}\n\nfunction limitValueLength() {\n  let value = currentValue.value\n\n  if (isNull(value)) {\n    currentLength.value = 0\n\n    return\n  }\n\n  const maxLength = props.maxLength\n\n  if (maxLength && value.length > maxLength) {\n    value = value.slice(0, maxLength)\n  }\n\n  currentLength.value = value.length\n  currentValue.value = value\n}\n\nfunction copyValue() {\n  const textarea = document.createElement('textarea')\n\n  textarea.style.height = '0'\n  textarea.setAttribute('readonly', 'readonly')\n  textarea.value = currentValue.value\n  document.body.appendChild(textarea)\n  textarea.select()\n\n  const isSuccess = document.execCommand('copy')\n\n  document.body.removeChild(textarea)\n\n  return isSuccess\n}\n\nconst delay = toNumber(props.delay)\nconst handleInput = props.debounce\n  ? debounce(handleChange, delay || 100)\n  : throttle(handleChange, delay || 16)\n\nfunction handleCompositionStart(event: CompositionEvent) {\n  composing.value = true\n  emitEvent(props.onCompositionStart, event)\n}\n\nfunction handleCompositionEnd(event: CompositionEvent) {\n  if (composing.value) {\n    composing.value = false\n\n    if (textarea.value) {\n      textarea.value.dispatchEvent(new Event('input'))\n    }\n  }\n\n  emitEvent(props.onCompositionStart, event)\n}\n</script>\n\n<template>\n  <div :id=\"idFor\" :class=\"className\" @click=\"textarea?.focus()\">\n    <textarea\n      v-bind=\"props.controlAttrs\"\n      ref=\"textarea\"\n      :class=\"[nh.be('control'), props.controlAttrs?.class, props.controlClass]\"\n      :value=\"currentValue\"\n      :rows=\"props.rows\"\n      :autofocus=\"props.autofocus\"\n      :autocomplete=\"autoComplete\"\n      :spellcheck=\"props.spellcheck\"\n      :disabled=\"props.disabled\"\n      :readonly=\"isReadonly\"\n      :placeholder=\"props.placeholder ?? locale.placeholder\"\n      :maxlength=\"props.maxLength > 0 ? props.maxLength : undefined\"\n      :name=\"props.name || props.controlAttrs?.name\"\n      :aria-labelledby=\"labelId\"\n      @blur=\"handleBlur\"\n      @focus=\"handleFocus\"\n      @keyup.enter=\"handleEnter\"\n      @keyup=\"handleKeyUp\"\n      @keypress=\"handleKeyPress\"\n      @keydown=\"handleKeyDown\"\n      @input=\"handleInput\"\n      @change=\"handleChange\"\n      @compositionstart=\"handleCompositionStart\"\n      @compositionend=\"handleCompositionEnd\"\n    ></textarea>\n    <div :class=\"nh.be('extra')\">\n      <Transition :name=\"nh.ns('fade')\" appear>\n        <div v-if=\"props.loading\" :class=\"nh.be('loading')\">\n          <Icon\n            v-bind=\"icons.loading\"\n            :effect=\"props.loadingEffect || icons.loading.effect\"\n            :icon=\"props.loadingIcon || icons.loading.icon\"\n            label=\"loading\"\n          ></Icon>\n        </div>\n      </Transition>\n      <div v-if=\"props.maxLength > 0\" :class=\"nh.be('count')\">\n        <slot name=\"count\" :value=\"currentValue\">\n          {{ props.maxLength === Infinity ? currentLength : `${currentLength}/${props.maxLength}` }}\n        </slot>\n      </div>\n    </div>\n  </div>\n</template>\n"],"names":["idFor","state","labelId","disabled","loading","validateField","getFieldValue","setFieldValue","useFieldStore","_a","textarea","props","useProps","__props","createStateProp","createIconProp","emit","__emit","nh","useNameHelper","locale","useLocale","toRef","icons","useIcons","focused","ref","currentValue","currentLength","composing","lastValue","isReadonly","computed","className","autoComplete","watch","value","limitValueLength","__expose","copyValue","options","handleFocus","event","emitEvent","handleBlur","handleChange","type","handleEnter","handleKeyDown","handleKeyPress","handleKeyUp","isNull","maxLength","isSuccess","delay","toNumber","handleInput","debounce","throttle","handleCompositionStart","handleCompositionEnd"],"mappings":"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"}