mirror of
https://github.com/speatzle/nfsense.git
synced 2025-09-13 15:19:08 +00:00
Nice form (#11)
* wip * vee-validate experiments * get test enabled form working * Make PillBar Properly work with ModelValue * Register NumberBox Globally * Rework NiceForm * Use new form props * Rework Definitions for new Form
This commit is contained in:
parent
2fb089ba73
commit
4c78d1da66
7 changed files with 153 additions and 74 deletions
|
@ -2,38 +2,60 @@
|
|||
|
||||
const props = defineModel<{
|
||||
title: string
|
||||
fields: {
|
||||
key: string,
|
||||
label: string,
|
||||
component: () => Component,
|
||||
props: any,
|
||||
}[]
|
||||
sections: {
|
||||
title: string
|
||||
fields: {
|
||||
key: string,
|
||||
label: string,
|
||||
as: string,
|
||||
props: any,
|
||||
default: any,
|
||||
enabled?: (values: Record<string, any>) => Boolean,
|
||||
rules?: (value: any) => true | string,
|
||||
}[],
|
||||
}[],
|
||||
modelValue: any,
|
||||
}>();
|
||||
let { title, fields } = $(props);
|
||||
|
||||
let { sections } = $(props);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="form">
|
||||
<h2>{{ title }}</h2>
|
||||
<template v-for="(field, index) in fields" :key="index">
|
||||
<label :for="field.key" v-text="field.label"/>
|
||||
<component :name="field.key" :is="field.component()" v-bind="field.props"/>
|
||||
<ValidationForm as="div" v-slot="{ values }" @submit="false">
|
||||
<template v-for="(section, index) in sections" :key="index">
|
||||
<h4 v-if="section.title">{{ section.title }}</h4>
|
||||
<div class="section">
|
||||
<template v-for="(field, index) in section.fields" :key="index">
|
||||
<template v-if="field.enabled ? field.enabled(values) : true">
|
||||
<label :for="field.key" v-text="field.label" />
|
||||
<Field :name="field.key" :as="field.as" :rules="field.rules" v-bind="field.props" />
|
||||
<ErrorMessage :name="field.key" />
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<p>{{ values }}</p>
|
||||
</ValidationForm>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.form {
|
||||
.section {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
padding: 0.5rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.form > :is(button, .button, h2) {
|
||||
|
||||
h4,
|
||||
p {
|
||||
grid-column: 1 / 3;
|
||||
}
|
||||
.form > :is(label) {
|
||||
grid-column: 1;
|
||||
|
||||
h4 {
|
||||
background-color: var(--cl-bg-hl);
|
||||
padding: 0.3rem;
|
||||
padding-left: 0.5rem;
|
||||
;
|
||||
}
|
||||
</style>
|
|
@ -10,25 +10,17 @@ const props = defineModel<{
|
|||
}>();
|
||||
let { options, modelValue } = $(props);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'selectionChanged'): void
|
||||
}>();
|
||||
|
||||
function select(option: any, index: number) {
|
||||
for(let opt of options) {
|
||||
opt.selected = false;
|
||||
onMounted(async() => {
|
||||
if (modelValue === undefined) {
|
||||
modelValue = 0
|
||||
}
|
||||
option.selected = true;
|
||||
modelValue = index;
|
||||
emit('selectionChanged');
|
||||
console.debug("selected", options);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<button class="option" v-for="(option, index) in options" :key="index" :class="{selected:option.selected}" @click="select(option, index)">
|
||||
<button class="option" v-for="(option, index) in options" :key="index" :class="{selected: modelValue == index}" @click="modelValue = index">
|
||||
<i class="material-icons" v-if="option.icon">{{ option.icon }}</i>
|
||||
{{ option.name }}
|
||||
</button>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue