Skip to content

Commit

Permalink
feat: added custom input components
Browse files Browse the repository at this point in the history
  • Loading branch information
YannicEl committed Jan 18, 2024
1 parent 91ea3b0 commit a9d9ea1
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 0 deletions.
15 changes: 15 additions & 0 deletions packages/lib/src/components/UInput.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<input ref="input" v-model="field.value" :class="classes" />
</template>

<script setup lang="ts">
import { Field } from '../useField';
import { getFieldAndClasses } from './utils';
const props = defineProps<{
field?: Field;
fieldName?: string;
}>();
const { field, classes } = getFieldAndClasses(props);
</script>
17 changes: 17 additions & 0 deletions packages/lib/src/components/USelect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<select v-model="field.value" :class="classes">
<slot />
</select>
</template>

<script setup lang="ts">
import { Field } from '../useField';
import { getFieldAndClasses } from './utils';
const props = defineProps<{
field?: Field;
fieldName?: string;
}>();
const { field, classes } = getFieldAndClasses(props);
</script>
18 changes: 18 additions & 0 deletions packages/lib/src/components/UTextarea.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<textarea v-model="field.value" :class="classes">
<slot />
</textarea
>
</template>

<script setup lang="ts">
import { Field } from '../useField';
import { getFieldAndClasses } from './utils';
const props = defineProps<{
field?: Field;
fieldName?: string;
}>();
const { field, classes } = getFieldAndClasses(props);
</script>
3 changes: 3 additions & 0 deletions packages/lib/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export { default as UField } from './UField.vue';
export { default as UForm } from './UForm.vue';
export { default as UFormGroup } from './UFormGroup.vue';
export { default as UInput } from './UInput.vue';
export { default as USelect } from './USelect.vue';
export { default as UTextarea } from './UTextarea.vue';
47 changes: 47 additions & 0 deletions packages/lib/src/components/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { ComputedRef, computed, useAttrs } from 'vue';
import { injectForm } from '../composables/useFormInject';
import { Field } from '../useField';
import { getClassnames } from '../utils';

export function getFieldAndClasses(props: { field?: Field; fieldName?: string }): {
field: ComputedRef<Field>;
classes: ComputedRef<Record<string, string>>;
} {
const field = computed(() => {
if (props.field) return props.field;

const attributes = useAttrs();
const { name } = attributes;

if (!name && !props.fieldName) {
console.warn('Input has not name prop');
return;
}

const form = injectForm();
if (!form) {
console.warn('Input is not inside a VForm component');
return;
}

const field = form.fields[props.fieldName ?? name];

if (!field) {
console.warn(`Form has no field "${name}"`);
return;
}

if ('values' in field) {
console.warn('Field is actually a field group');
return;
}

field.disabled = 'disabled' in attributes;

return field;
});

const classes = computed(() => (field.value ? getClassnames(field.value) : {}));

return { field, classes };
}

0 comments on commit a9d9ea1

Please sign in to comment.