Skip to content

Commit

Permalink
feat: refactors
Browse files Browse the repository at this point in the history
  • Loading branch information
YannicEl committed Jul 30, 2023
1 parent 8bf395b commit 1bf3c87
Show file tree
Hide file tree
Showing 14 changed files with 925 additions and 112 deletions.
48 changes: 41 additions & 7 deletions packages/docs/components/content/Test.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,53 @@
<template>
<VForm :form="form">
<FormGroup>
<input type="text" name="test" />
</FormGroup>
<VForm :form="form" class="flex flex-col gap-4" @submit="onSubmit" @v-submit="onVSubmit">
<VLabel class="flex flex-col">
Label {{ form.fields.test.value }}
<input type="text" name="test" required />
</VLabel>

<VLabel fieldName="select" class="flex flex-col">
Select
<select name="select2">
<option value="hallo">hallo</option>
<option value="zwallo">zwallo</option>
<option value="drallo">drallo</option>
</select>
</VLabel>

<button>submit</button>
</VForm>

<pre
<VLabel :field="form.fields.test2" class="flex flex-col mt-4">
Label
<input type="text" name="test2" disabled required />
</VLabel>

<button @click="form.disabled ? form.enable() : form.disable()">
{{ form.disabled ? 'enable' : 'disable' }}
</button>

<pre class="mt-6"
>{{ form.values }}
</pre>
</template>

<script setup lang="ts">
import { VForm, useForm, FormGroup } from '@vuetils/form';
import { required } from '@vuetils/form';
import { VForm, useForm, VLabel } from '@vuetils/form';
const form = useForm({
test: [''],
test: ['', [required]],
test2: [''],
select: ['drallo'],
});
function onSubmit() {
console.log('on submit');
}
function onVSubmit() {
console.log('on v submit');
}
</script>

<style></style>
5 changes: 5 additions & 0 deletions packages/docs/content/3.test/1.test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Test

::test
Hi
::
2 changes: 1 addition & 1 deletion packages/docs/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ export default defineNuxtConfig({
// https://github.com/nuxt-themes/docus
extends: '@nuxt-themes/docus',

modules: [],
modules: ['@unocss/nuxt'],
});
1 change: 1 addition & 0 deletions packages/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"devDependencies": {
"@nuxt-themes/docus": "^1.14.4",
"@types/node": "^18.17.1",
"@unocss/nuxt": "^0.54.0",
"nuxt": "^3.6.5",
"wrangler": "^3.4.0"
}
Expand Down
1 change: 1 addition & 0 deletions packages/lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
},
"devDependencies": {
"@types/node": "^18.17.1",
"@vitejs/plugin-vue": "^4.2.3",
"@vuetils/form": "workspace:latest",
"typescript": "^5.1.6",
"vite": "^4.4.7",
Expand Down
91 changes: 44 additions & 47 deletions packages/lib/src/components/FormGroup.vue
Original file line number Diff line number Diff line change
@@ -1,85 +1,82 @@
<template>
<Render />
{{ field?.value }}
<label>
<LabelContent />
<Render />
</label>
</template>

<script setup lang="ts">
import { computed, h, useSlots, watch } from 'vue';
import { computed, h, useSlots } from 'vue';
import { injectForm } from '../composables/useFormInject';
import type { Field } from '../useField';
import { getClassnames } from '../utils';
const props = defineProps<{
field?: Field;
fieldName?: string;
}>();
const form = injectForm();

const slots = useSlots();
const defaultSlots = computed(() => {
console.log('slots computed');
const defaultSlots = slots.default?.();
return Array.isArray(defaultSlots) ? defaultSlots : [];
});
const defaultSlots = computed(() => slots.default?.() ?? []);
const inputNode = computed(() => {
console.log('inputNode computed');
return defaultSlots.value.find((slot) => slot.type === 'input');
const labelNodes = computed(() => {
return defaultSlots.value.filter((slot) => slot.type !== 'input' && slot.type !== 'select');
});
const labelNodes = computed(() => {
console.log('labelNodes computed');
return defaultSlots.value.filter((slot) => slot.type !== 'input');
const LabelContent = () => {
return labelNodes.value;
};
const inputNode = computed(() => {
return defaultSlots.value.find((slot) => slot.type === 'input' || slot.type === 'select');
});
const field = computed(() => {
if (props.field) return props.field;
const { name } = inputNode.value?.props || {};
const attributes = inputNode.value?.props ?? {};
const { name } = attributes;
if (!name) {
if (!name && !props.fieldName) {
console.warn('Input has not name prop');
return;
}
const field = form?.fields[name];
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;
}
return field;
});
field.disabled = 'disabled' in attributes;
watch(field, (change) => {
console.log('watch');
console.log(change);
return field;
});
const Render = () => {
console.log('rerender');

console.log(field.value?.value);

const children = labelNodes.value;
if (inputNode.value) {
console.log('hi');

const input = h(inputNode.value, {
type: field.value?.value,
value: field.value?.value + '123',
onInput(event: InputEvent) {
if (!field.value) return;
field.value.value = (event.target as HTMLInputElement).value;
},
});

console.log(input);

children.push(input);
}

return h('label', {}, children);
if (!inputNode.value) return;
if (!field.value) return;
return h(inputNode.value, {
value: field.value.value,
onInput(event: InputEvent) {
if (!field.value) return;
field.value.value = (event.target as HTMLInputElement).value;
},
onChange(event: Event) {
if (!field.value) return;
field.value.value = (event.target as HTMLInputElement).value;
},
disabled: field.value.disabled,
class: getClassnames(field.value),
});
};
</script>

Expand Down
27 changes: 0 additions & 27 deletions packages/lib/src/components/FormSelect.vue

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
<template>
<form
@submit.prevent="onSubmit"
:class="{
valid,
invalid,
submitted,
}"
>
<slot :form="form"></slot>
<form @submit.prevent="onSubmit" :class="classNames">
<slot />
</form>
</template>

<script setup lang="ts" generic="T">
import { toRefs } from 'vue';
import type { Form } from '../useForm';
import { provideForm } from '../composables/useFormInject';
import { getClassnames } from '../utils';
import { computed } from 'vue';
const { form } = defineProps<{
form: Form<T>;
Expand All @@ -26,7 +20,7 @@ const emits = defineEmits<{
provideForm(form);
const { valid, invalid, submitted } = toRefs(form);
const classNames = computed(() => getClassnames(form));
function onSubmit() {
form.submitted = true;
Expand Down
8 changes: 3 additions & 5 deletions packages/lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ export * from './useField';
export * from './useForm';
export * from './validators';

import VForm from './components/Form.vue';
import FormGroup from './components/FormGroup.vue';
import FormInput from './components/FormInput.vue';
import FormSelect from './components/FormSelect.vue';
import VLabel from './components/FormGroup.vue';
import VForm from './components/VForm.vue';

export { FormGroup, FormInput, FormSelect, VForm };
export { VForm, VLabel };
3 changes: 3 additions & 0 deletions packages/lib/src/useField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface Field<T = any> {
disabled: boolean;
enabled: boolean;
dirty: boolean;
pristine: boolean;
async: boolean;
pending: boolean;

Expand Down Expand Up @@ -87,6 +88,7 @@ export function useField<T>(
const enable = () => (disabled.value = false);

const dirty = ref(false);
const pristine = computed(() => !dirty.value);
watch(value, () => {
dirty.value = true;
});
Expand Down Expand Up @@ -120,6 +122,7 @@ export function useField<T>(
disabled,
enabled,
dirty,
pristine,
async,
pending,

Expand Down

0 comments on commit 1bf3c87

Please sign in to comment.