feat: 更新表单组件,简化代码结构并添加调试插件
Some checks failed
/ test (push) Failing after 26s
/ surge (push) Successful in 39s

This commit is contained in:
严浩
2024-11-25 10:33:01 +08:00
parent 07320f09b0
commit 7bb954e348
11 changed files with 152 additions and 185 deletions

View File

@ -5,6 +5,9 @@
"[vue]": { "[vue]": {
"editor.defaultFormatter": "Vue.volar", "editor.defaultFormatter": "Vue.volar",
}, },
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.formatOnSaveMode": "file", "editor.formatOnSaveMode": "file",
"typescript.tsdk": "node_modules/typescript/lib", "typescript.tsdk": "node_modules/typescript/lib",

View File

@ -1,40 +0,0 @@
import type { FormKitNode } from "@formkit/core";
const legends = ['checkbox_multi', 'radio_multi', 'repeater', 'transferlist'];
export function addAsteriskPlugin(node: FormKitNode) {
if (['button', 'submit', 'hidden', 'group', 'list', 'meta'].includes(node.props.type)) return;
node.on('created', () => {
const legendOrLabel = legends.includes(`${node.props.type}${node.props.options ? '_multi' : ''}`) ? 'legend' : 'label';
console.group('[node created]', node.props.label || node.props.submitLabel)
console.debug(`node :>> `, node);
console.debug(`node.props.definition :>> `, node.props.definition);
// if (typeof node.props.definition!.schema === 'function') {
// console.debug(`node.props.definition.schema.call :>> `, node.props.definition!.schema.call(node.props.definition, {}));
// }
console.debug(`legendOrLabel :>> `, legendOrLabel);
console.groupEnd()
if (!node.props.definition) return;
if (node.props.definition.schemaMemoKey) {
node.props.definition.schemaMemoKey += `${node.props.options ? '_multi' : ''}_add_asterisk`;
};
const schemaFn = node.props.definition.schema!;
node.props.definition!.schema = (sectionsSchema = {}) => {
sectionsSchema[legendOrLabel] = {
children: ['$label', {
$el: 'span',
if: '$state.required',
attrs: {
class: '$classes.asterisk',
},
children: ['*']
}]
}
return typeof schemaFn === 'function' ? schemaFn(sectionsSchema) : schemaFn
}
})
}

View File

@ -1,25 +0,0 @@
import {
checkbox,
form,
group,
list,
number,
range,
submit,
text,
textarea,
} from "@formkit/inputs";
// https://unocss.dev/presets/wind#differences-from-tailwind-css
export const fkLibrary = {
text,
form,
submit,
group,
checkbox,
range,
list,
number,
textarea,
};

View File

@ -0,0 +1,37 @@
import type { FormKitExtendableSchemaRoot, FormKitNode } from '@formkit/core';
const legends = ['checkbox_multi', 'radio_multi', 'repeater', 'transferlist'];
export function addAsteriskPlugin(node: FormKitNode) {
if (['button', 'submit', 'hidden', 'group', 'list', 'meta'].includes(node.props.type)) return;
node.on('created', () => {
const legendOrLabel = legends.includes(`${node.props.type}${node.props.options ? '_multi' : ''}`)
? 'legend'
: 'label';
if (!node.props.definition) return;
if (node.props.definition.schemaMemoKey) {
node.props.definition.schemaMemoKey += `${node.props.options ? '_multi' : ''}_add_asterisk`;
}
const schemaFn = node.props.definition.schema! as FormKitExtendableSchemaRoot;
node.props.definition!.schema = (sectionsSchema = {}) => {
sectionsSchema[legendOrLabel] = {
children: [
'$label',
{
$el: 'span',
if: '$state.required',
attrs: {
class: '$classes.asterisk',
},
children: ['*'],
},
],
};
return schemaFn(sectionsSchema);
};
});
}

View File

@ -0,0 +1,10 @@
export function debugPlugin(node: import('@formkit/core').FormKitNode) {
if (['button', 'submit', 'hidden', 'group', 'list', 'meta'].includes(node.props.type)) return;
node.on('created', () => {
console.group('[node created]', node.props.label || node.props.submitLabel);
console.debug(`node :>> `, node);
console.debug(`node.props.definition :>> `, node.props.definition);
console.groupEnd();
});
}

View File

@ -26,23 +26,11 @@ import type { FormKitNode } from '@formkit/core'
* ``` * ```
**/ **/
export function rootClasses (sectionName: string, node: FormKitNode): Record<string, boolean> { export function rootClasses (sectionName: string, node: FormKitNode): Record<string, boolean> {
const key = `${node.props.type}__${sectionName}` const key = `${node.props.type}__${sectionName}`
const semanticKey = `formkit-${sectionName}` const semanticKey = `formkit-${sectionName}`
const familyKey = node.props.family ? `family:${node.props.family}__${sectionName}` : '' const familyKey = node.props.family ? `family:${node.props.family}__${sectionName}` : ''
const memoKey = `${key}__${familyKey}` const memoKey = `${key}__${familyKey}`
if (!(memoKey in classes)) { if (!(memoKey in classes)) {
setTimeout(() => {
// console.group(`rootClasses(${sectionName}) ${memoKey}`)
// console.debug(`key :>> `, key);
// console.debug(`semanticKey :>> `, semanticKey);
// console.debug(`familyKey :>> `, familyKey);
// console.debug(`memoKey :>> `, memoKey);
// console.debug(`classes[key] :>> `, classes[key]);
// console.debug(`globals[sectionName] :>> `, globals[sectionName]);
// console.groupEnd()
}, 1000);
const sectionClasses = classes[key] ?? globals[sectionName] ?? {} const sectionClasses = classes[key] ?? globals[sectionName] ?? {}
sectionClasses[semanticKey] = true sectionClasses[semanticKey] = true
if (familyKey in classes) { if (familyKey in classes) {
@ -58,7 +46,7 @@ export function rootClasses(sectionName: string, node: FormKitNode): Record<stri
* These classes have already been merged with globals using tailwind-merge * These classes have already been merged with globals using tailwind-merge
* and are ready to be used directly in the theme. * and are ready to be used directly in the theme.
**/ **/
export const classes: Record<string, Record<string, boolean>> = { const classes: Record<string, Record<string, boolean>> = {
"family:button__wrapper": { "family:button__wrapper": {
"group-data-[disabled=true]:grayscale": true "group-data-[disabled=true]:grayscale": true
}, },
@ -3300,7 +3288,7 @@ export const classes: Record<string, Record<string, boolean>> = {
* Globals are merged prior to generating this file — these are included for * Globals are merged prior to generating this file — these are included for
* any other non-matching inputs. * any other non-matching inputs.
**/ **/
export const globals: Record<string, Record<string, boolean>> = { const globals: Record<string, Record<string, boolean>> = {
"outer": { "outer": {
"group": true, "group": true,
"max-w-[20em]": true, "max-w-[20em]": true,

View File

@ -1,65 +1,59 @@
import { createAutoAnimatePlugin, createAutoHeightTextareaPlugin } from '@formkit/addons' import { createAutoAnimatePlugin, createAutoHeightTextareaPlugin } from '@formkit/addons';
import type { FormKitNode, FormKitOptions } from '@formkit/core' import { autoAnimatePlugin } from '@formkit/auto-animate/vue';
import { createI18nPlugin, zh } from '@formkit/i18n' import type { FormKitOptions } from '@formkit/core';
import { genesisIcons } from '@formkit/icons' import { register as decodeErrors } from '@formkit/dev';
import { createLibraryPlugin, submit, text } from '@formkit/inputs' import { createI18nPlugin, zh } from '@formkit/i18n';
import { createProPlugin, toggle } from '@formkit/pro' import { createLibraryPlugin, submit, text } from '@formkit/inputs';
import * as defaultRules from '@formkit/rules' import * as defaultRules from '@formkit/rules';
import { createThemePlugin } from '@formkit/themes' import { createValidationPlugin } from '@formkit/validation';
import { createValidationPlugin } from '@formkit/validation' import { /* defaultConfig, */ bindings, plugin /* defaultConfig */ } from '@formkit/vue';
import { /* defaultConfig, */ bindings, createInput } from '@formkit/vue' import type { App } from 'vue';
import { addAsteriskPlugin } from './formkit.config.addAsteriskPlugin' import { addAsteriskPlugin } from './formkit.config.plugin.addAsteriskPlugin';
// import { fkLibrary } from './formkit.config.fkLibrary' import { debugPlugin } from './formkit.config.plugin.debug';
// import { rootClasses } from "./formkit.config.theme" import { form } from '@/__fk-inputs__/inputs/form';
import HeadlessuiToggle from "./src/headlessui-switch.vue"
import { register as decodeErrors } from '@formkit/dev'
decodeErrors();
const validation = createValidationPlugin(defaultRules)
const theme = undefined;
const icons = genesisIcons;
// const apiKey = 'fk-6cdd5192223' // const apiKey = 'fk-6cdd5192223'
export default { const config: FormKitOptions = {
plugins: [ plugins: [
...[
// createProPlugin(apiKey, { toggle }), // createProPlugin(apiKey, { toggle }),
// createLibraryPlugin(fkLibrary), // createLibraryPlugin(fkLibrary),
createLibraryPlugin({ createLibraryPlugin({
text, form,
submit, submit,
text,
}), }),
// createLibraryPlugin( // createLibraryPlugin(
// { // {
// 'headlessuiSwitch': createInput(HeadlessuiToggle), // 'headlessuiSwitch': createInput(HeadlessuiToggle),
// } // }
// ), // ),
createThemePlugin(theme, icons/* , iconLoaderUrl, iconLoader */), ],
// createThemePlugin(
// theme: undefined /* icons: genesisIcons, iconLoaderUrl, iconLoader */,
// ),
bindings, bindings,
createI18nPlugin({ zh }), createI18nPlugin({ zh }),
validation, createValidationPlugin(defaultRules),
addAsteriskPlugin, addAsteriskPlugin,
createAutoHeightTextareaPlugin(/* https://github.com/formkit/formkit/blob/ac1947a305eb5082ba95f53800305d080787cb32/packages/addons/src/plugins/autoHeightTextarea.ts */),
// https://github.com/formkit/formkit/blob/ac1947a305eb5082ba95f53800305d080787cb32/packages/addons/src/plugins/autoHeightTextarea.ts createAutoAnimatePlugin(
createAutoHeightTextareaPlugin(),
// https://auto-animate.formkit.com/#usage // https://auto-animate.formkit.com/#usage
// https://github.com/formkit/auto-animate/ // https://github.com/formkit/auto-animate/
// https://github.com/formkit/formkit/blob/46d64d05c1b37875fc6227853f2bcfa987550c91/packages/addons/src/plugins/autoAnimatePlugin.ts // https://github.com/formkit/formkit/blob/46d64d05c1b37875fc6227853f2bcfa987550c91/packages/addons/src/plugins/autoAnimatePlugin.ts
createAutoAnimatePlugin(
{ {
duration: 250, duration: 250,
easing: 'ease-in-out', easing: 'ease-in-out',
}, },
// { {
// /* optional animation targets object */ /* optional animation targets object */
// // default: // default:
// global: ['outer', 'inner'], global: ['outer', 'inner'],
// form: ['form'], form: ['form'],
// repeater: ['items'], repeater: ['items'],
// } },
) ),
debugPlugin,
], ],
config: { config: {
// rootClasses: false, // rootClasses: false,
@ -68,4 +62,10 @@ export default {
// console.debug(`sectionName :>> `, sectionName); // console.debug(`sectionName :>> `, sectionName);
// } // }
}, },
} satisfies FormKitOptions };
export function setupFormKit(app: App) {
decodeErrors();
app.use(plugin, config);
app.use(autoAnimatePlugin); // v-auto-animate="{ duration: 100 }"
}

View File

@ -1,16 +1,15 @@
import { FormKitTypeDefinition } from '@formkit/core' import { FormKitTypeDefinition } from '@formkit/core'
import { import {
outer, casts,
inner,
wrapper,
label,
help, help,
icon, icon,
inner,
label,
outer,
prefix, prefix,
suffix, suffix,
textInput, textInput,
casts, wrapper
createSection,
} from '@formkit/inputs' } from '@formkit/inputs'
import { messages } from '../sections/messages' import { messages } from '../sections/messages'

View File

@ -31,7 +31,7 @@ async function submit() {
label: 'font-medium block' label: 'font-medium block'
} }
}" }"
:type="form" type="form"
#default="{ value }" #default="{ value }"
@submit="submit" @submit="submit"
submit-label="提交 " submit-label="提交 "

View File

@ -1,13 +1,9 @@
import { autoAnimatePlugin } from '@formkit/auto-animate/vue' import Aura from "@primevue/themes/aura";
import { plugin, /* defaultConfig */ } from '@formkit/vue'
import { createApp } from 'vue'
import formKitConfig from '../formkit.config'
import App from './App.vue'
import PrimeVue from "primevue/config"; import PrimeVue from "primevue/config";
import Aura from '@primevue/themes/aura'; import ToastService from "primevue/toastservice";
import ToastService from 'primevue/toastservice'; import { createApp } from "vue";
import { setupFormKit } from "../formkit.config";
import App from "./App.vue";
// import '@unocss/reset/normalize.css' // import '@unocss/reset/normalize.css'
// import '@unocss/reset/sanitize/sanitize.css' // import '@unocss/reset/sanitize/sanitize.css'
@ -16,16 +12,15 @@ import ToastService from 'primevue/toastservice';
// import '@unocss/reset/tailwind-compat.css' // import '@unocss/reset/tailwind-compat.css'
// import '@unocss/reset/tailwind.css' // import '@unocss/reset/tailwind.css'
import 'virtual:uno.css' import "primeicons/primeicons.css";
import 'primeicons/primeicons.css' import "virtual:uno.css";
const app = createApp(App) const app = createApp(App);
app.use(PrimeVue, { theme: { preset: Aura } }); app.use(PrimeVue, { theme: { preset: Aura } });
app.use(ToastService); app.use(ToastService);
// https://github.dev/formkit/auto-animate/blob/master/docs/src/examples/formkit/ActualFormKit.vue // https://github.dev/formkit/auto-animate/blob/master/docs/src/examples/formkit/ActualFormKit.vue
app.use(autoAnimatePlugin) // v-auto-animate="{ duration: 100 }"
app.use(plugin, formKitConfig) setupFormKit(app);
app.mount('#app')
app.mount("#app");

View File

@ -220,7 +220,7 @@ onMounted(() => {
<div class="bg-gray-100 p-4 rounded-xl dark:bg-gray-800"> <div class="bg-gray-100 p-4 rounded-xl dark:bg-gray-800">
<h2 class="font-bold text-lg mb-4 color:gray-800 dark:text-white">Pro Inputs</h2> <h2 class="font-bold text-lg mb-4 color:gray-800 dark:text-white">Pro Inputs</h2>
<FormKit type="toggle" /> <!-- <FormKit type="toggle" /> -->
</div> </div>
</FormKit> </FormKit>