<commit_before>import { computed, h, defineComponent } from 'vue';
import { getConfig } from './config';
import { useField } from './useField';
import { useRefsObjToComputed, normalizeChildren, isHTMLTag, hasCheckedAttr } from './utils';

export const Field = defineComponent({
  name: 'Field',
  inheritAttrs: false,
  props: {
    as: {
      type: [String, Object],
      default: undefined,
    },
    name: {
      type: String,
      required: true,
    },
    rules: {
      type: [Object, String, Function],
      default: null,
    },
    immediate: {
      type: Boolean,
      default: false,
    },
    bails: {
      type: Boolean,
      default: () => getConfig().bails,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  setup(props, ctx) {
    const fieldName = props.name;
    // FIXME: is this right?
    const disabled = computed(() => props.disabled as boolean);
    const rules = computed(() => props.rules);

    const {
      errors,
      value,
      errorMessage,
      validate: validateField,
      handleChange,
      onBlur,
      reset,
      meta,
      aria,
      checked,
    } = useField(fieldName, rules, {
      immediate: props.immediate as boolean,
      bails: props.bails as boolean,
      disabled,
      type: ctx.attrs.type as string,
      initialValue: hasCheckedAttr(ctx.attrs.type) ? ctx.attrs.modelValue : ctx.attrs.value,
      valueProp: ctx.attrs.value,
    });

    const unwrappedMeta = useRefsObjToComputed(meta);

    const slotProps = computed(() => {
      const fieldProps: Record<string, any> = {
        name: fieldName,
        disabled: props.disabled,
        onInput: handleChange,
        onChange: handleChange,
        'onUpdate:modelValue': handleChange,
        onBlur: onBlur,
      };

      if (hasCheckedAttr(ctx.attrs.type) && checked) {
        fieldProps.checked = checked.value;
        // redundant for checkboxes and radio buttons
        delete fieldProps.onInput;
      } else {
        fieldProps.value = value.value;
      }

      return {
        field: fieldProps,
        aria: aria.value,
        meta: unwrappedMeta.value,
        errors: errors.value,
        errorMessage: errorMessage.value,
        validate: validateField,
        reset,
        handleChange,
      };
    });

    return () => {
      let tag = props.as;
      if (!props.as && !ctx.slots.default) {
        tag = 'input';
      }

      const children = normalizeChildren(ctx, slotProps.value);
      if (tag) {
        return h(
          tag,
          {
            ...ctx.attrs,
            ...slotProps.value.field,
            ...(isHTMLTag(tag) ? slotProps.value.aria : {}),
          },
          children
        );<commit_msg>feat: added basic v-model support<commit_after>import { computed, h, defineComponent } from 'vue';
import { getConfig } from './config';
import { useField } from './useField';
import { useRefsObjToComputed, normalizeChildren, isHTMLTag, hasCheckedAttr } from './utils';

export const Field = defineComponent({
  name: 'Field',
  inheritAttrs: false,
  props: {
    as: {
      type: [String, Object],
      default: undefined,
    },
    name: {
      type: String,
      required: true,
    },
    rules: {
      type: [Object, String, Function],
      default: null,
    },
    immediate: {
      type: Boolean,
      default: false,
    },
    bails: {
      type: Boolean,
      default: () => getConfig().bails,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  setup(props, ctx) {
    const fieldName = props.name;
    // FIXME: is this right?
    const disabled = computed(() => props.disabled as boolean);
    const rules = computed(() => props.rules);

    const {
      errors,
      value,
      errorMessage,
      validate: validateField,
      handleChange,
      onBlur,
      reset,
      meta,
      aria,
      checked,
    } = useField(fieldName, rules, {
      immediate: props.immediate as boolean,
      bails: props.bails as boolean,
      disabled,
      type: ctx.attrs.type as string,
      initialValue: hasCheckedAttr(ctx.attrs.type) ? ctx.attrs.modelValue : ctx.attrs.modelValue || ctx.attrs.value,
      valueProp: ctx.attrs.value,
    });

    // If there is a v-model applied on the component we need to emit the `update:modelValue` whenever the value binding changes
    const onChangeHandler =
      'modelValue' in ctx.attrs
        ? function handleChangeWithModel(e: any) {
            handleChange(e);
            ctx.emit('update:modelValue', value.value);
          }
        : handleChange;

    const unwrappedMeta = useRefsObjToComputed(meta);

    const slotProps = computed(() => {
      const fieldProps: Record<string, any> = {
        name: fieldName,
        disabled: props.disabled,
        onInput: onChangeHandler,
        onChange: onChangeHandler,
        'onUpdate:modelValue': onChangeHandler,
        onBlur: onBlur,
      };

      if (hasCheckedAttr(ctx.attrs.type) && checked) {
        fieldProps.checked = checked.value;
        // redundant for checkboxes and radio buttons
        delete fieldProps.onInput;
      } else {
        fieldProps.value = value.value;
      }

      return {
        field: fieldProps,
        aria: aria.value,
        meta: unwrappedMeta.value,
        errors: errors.value,
        errorMessage: errorMessage.value,
        validate: validateField,
        reset,
        handleChange: onChangeHandler,
      };
    });

    return () => {
      let tag = props.as;
      if (!props.as && !ctx.slots.default) {
        tag = 'input';
      }

      const children = normalizeChildren(ctx, slotProps.value);
      if (tag) {
        return h(
          tag,
          {
            ...ctx.attrs,
            ...slotProps.value.field,
            ...(isHTMLTag(tag) ? slotProps.value.aria : {}),
          },
          children
        );
{'fraction_non_alphanumeric': 0.1193143245078072, 'fraction_numerical': 0.0, 'mean_word_length': 2.0251540041067764, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '328431', 'n_tokens_mistral': 1714, 'n_tokens_neox': 1699, 'n_words': 420}