feat: 更新表单组件,简化代码结构并添加调试插件
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -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",
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
@ -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,
|
|
||||||
};
|
|
37
formkit.config.plugin.addAsteriskPlugin.ts
Normal file
37
formkit.config.plugin.addAsteriskPlugin.ts
Normal 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);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
10
formkit.config.plugin.debug.ts
Normal file
10
formkit.config.plugin.debug.ts
Normal 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();
|
||||||
|
});
|
||||||
|
}
|
@ -10,55 +10,43 @@ import type { FormKitNode } from '@formkit/core'
|
|||||||
* @theme - regenesis
|
* @theme - regenesis
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the theme function itself, it should be imported and used as the
|
* This is the theme function itself, it should be imported and used as the
|
||||||
* config.rootClasses function. For example:
|
* config.rootClasses function. For example:
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* import { theme } from './formkit.theme'
|
* import { theme } from './formkit.theme'
|
||||||
* import { defineFormKitConfig } from '@formkit/vue'
|
* import { defineFormKitConfig } from '@formkit/vue'
|
||||||
*
|
*
|
||||||
* export default defineFormKitConfig({
|
* export default defineFormKitConfig({
|
||||||
* config: {
|
* config: {
|
||||||
* rootClasses: theme
|
* rootClasses: theme
|
||||||
* }
|
* }
|
||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
**/
|
**/
|
||||||
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)) {
|
const sectionClasses = classes[key] ?? globals[sectionName] ?? {}
|
||||||
setTimeout(() => {
|
sectionClasses[semanticKey] = true
|
||||||
// console.group(`rootClasses(${sectionName}) ${memoKey}`)
|
if (familyKey in classes) {
|
||||||
// console.debug(`key :>> `, key);
|
classes[memoKey] = { ...classes[familyKey], ...sectionClasses }
|
||||||
// console.debug(`semanticKey :>> `, semanticKey);
|
} else {
|
||||||
// console.debug(`familyKey :>> `, familyKey);
|
classes[memoKey] = sectionClasses
|
||||||
// console.debug(`memoKey :>> `, memoKey);
|
}
|
||||||
// console.debug(`classes[key] :>> `, classes[key]);
|
}
|
||||||
// console.debug(`globals[sectionName] :>> `, globals[sectionName]);
|
return classes[memoKey] ?? { [semanticKey]: true }
|
||||||
// console.groupEnd()
|
}
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
const sectionClasses = classes[key] ?? globals[sectionName] ?? {}
|
|
||||||
sectionClasses[semanticKey] = true
|
|
||||||
if (familyKey in classes) {
|
|
||||||
classes[memoKey] = { ...classes[familyKey], ...sectionClasses }
|
|
||||||
} else {
|
|
||||||
classes[memoKey] = sectionClasses
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return classes[memoKey] ?? { [semanticKey]: true }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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,
|
||||||
|
@ -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 }),
|
...[
|
||||||
// createLibraryPlugin(fkLibrary),
|
// createProPlugin(apiKey, { toggle }),
|
||||||
createLibraryPlugin({
|
// createLibraryPlugin(fkLibrary),
|
||||||
text,
|
createLibraryPlugin({
|
||||||
submit,
|
form,
|
||||||
}),
|
submit,
|
||||||
// createLibraryPlugin(
|
text,
|
||||||
// {
|
}),
|
||||||
// 'headlessuiSwitch': createInput(HeadlessuiToggle),
|
// createLibraryPlugin(
|
||||||
// }
|
// {
|
||||||
|
// 'headlessuiSwitch': createInput(HeadlessuiToggle),
|
||||||
|
// }
|
||||||
|
// ),
|
||||||
|
],
|
||||||
|
// createThemePlugin(
|
||||||
|
// theme: undefined /* icons: genesisIcons, iconLoaderUrl, iconLoader */,
|
||||||
// ),
|
// ),
|
||||||
createThemePlugin(theme, icons/* , 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
|
|
||||||
createAutoHeightTextareaPlugin(),
|
|
||||||
|
|
||||||
// https://auto-animate.formkit.com/#usage
|
|
||||||
// https://github.com/formkit/auto-animate/
|
|
||||||
// https://github.com/formkit/formkit/blob/46d64d05c1b37875fc6227853f2bcfa987550c91/packages/addons/src/plugins/autoAnimatePlugin.ts
|
|
||||||
createAutoAnimatePlugin(
|
createAutoAnimatePlugin(
|
||||||
|
// https://auto-animate.formkit.com/#usage
|
||||||
|
// https://github.com/formkit/auto-animate/
|
||||||
|
// https://github.com/formkit/formkit/blob/46d64d05c1b37875fc6227853f2bcfa987550c91/packages/addons/src/plugins/autoAnimatePlugin.ts
|
||||||
{
|
{
|
||||||
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 }"
|
||||||
|
}
|
||||||
|
@ -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'
|
||||||
|
|
||||||
|
@ -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="提交 ✨"
|
||||||
|
27
src/main.ts
27
src/main.ts
@ -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");
|
||||||
|
@ -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>
|
||||||
|
Reference in New Issue
Block a user