diff --git a/apps/docs/.vitepress/config.mts b/apps/docs/.vitepress/config.mts index ba7b598..1710d9e 100644 --- a/apps/docs/.vitepress/config.mts +++ b/apps/docs/.vitepress/config.mts @@ -1,5 +1,6 @@ import { defineConfig } from 'vitepress' import { groupIconMdPlugin, groupIconVitePlugin } from 'vitepress-plugin-group-icons' +import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs' import path from 'path' // https://vitepress.dev/reference/site-config @@ -11,6 +12,7 @@ export default defineConfig({ markdown: { config(md) { md.use(groupIconMdPlugin) + md.use(tabsMarkdownPlugin) } }, themeConfig: { @@ -34,6 +36,12 @@ export default defineConfig({ { text: 'Custom validators', link: '/guide/customization/custom-validators' } ] }, + { + text: 'Components', + items: [ + { text: 'FormLabel', link: '/guide/components/FormLabel' }, + ] + }, { text: 'Composables', items: [ @@ -41,7 +49,9 @@ export default defineConfig({ { text: 'useFieldEmits', link: '/guide/composables/useFieldEmits' }, { text: 'useFieldProps', link: '/guide/composables/useFieldProps' }, { text: 'useFieldValidate', link: '/guide/composables/useFieldValidate' }, - { text: 'useFormModel', link: '/guide/composables/useFormModel' } + { text: 'useFormModel', link: '/guide/composables/useFormModel' }, + { text: 'useLabelIcon', link: '/guide/composables/useLabelIcon' }, + { text: 'useValidation', link: '/guide/composables/useValidation' } ] }, { diff --git a/apps/docs/.vitepress/theme/index.js b/apps/docs/.vitepress/theme/index.js index ea4628c..b63094d 100644 --- a/apps/docs/.vitepress/theme/index.js +++ b/apps/docs/.vitepress/theme/index.js @@ -1,6 +1,8 @@ import DefaultTheme from 'vitepress/theme' import VueFormGenerator from '@/index' +import { enhanceAppWithTabs } from 'vitepress-plugin-tabs/client' + import './index.css' import '@/scss/themes/basic.scss' import 'virtual:group-icons.css' @@ -8,6 +10,7 @@ import 'virtual:group-icons.css' export default { extends: DefaultTheme, enhanceApp({ app }) { + enhanceAppWithTabs(app) app.use(VueFormGenerator, { messages: { productCodeValidator: 'Your product code is invalid' diff --git a/apps/docs/guide/components/FormLabel.md b/apps/docs/guide/components/FormLabel.md new file mode 100644 index 0000000..03224c2 --- /dev/null +++ b/apps/docs/guide/components/FormLabel.md @@ -0,0 +1,43 @@ +--- +outline: [2,3] +--- +# FormLabel +> A label component that automatically handles the labelIcon property and position. + +## Usage +:::code-group +```vue [template] + +``` +```vue [script setup] + +``` +::: + +## Props +### `labelIcon` +Either a string webfont class, a component or `LabelIconDefinition`. + +### `labelIconPosition` +Either `'left'`, `'right'` or `null` + +### `label` +Label as set by the field schema. + +### `fieldId` +Computed field id, taken from props. diff --git a/apps/docs/guide/composables/useFieldEmits.md b/apps/docs/guide/composables/useFieldEmits.md index 1eadcf9..a3f80d5 100644 --- a/apps/docs/guide/composables/useFieldEmits.md +++ b/apps/docs/guide/composables/useFieldEmits.md @@ -13,6 +13,15 @@ const emits = defineEmits(useFieldEmits()) ``` +## TypeScript alternative +```vue + +``` + ## Emits ### `onInput` diff --git a/apps/docs/guide/composables/useFieldProps.md b/apps/docs/guide/composables/useFieldProps.md index c0ce97a..1907d14 100644 --- a/apps/docs/guide/composables/useFieldProps.md +++ b/apps/docs/guide/composables/useFieldProps.md @@ -16,6 +16,20 @@ const { field, model } = toRefs(props) ``` +## TypeScript alternative +```vue + +``` + ## Props ### `id` diff --git a/apps/docs/guide/composables/useFieldValidate.md b/apps/docs/guide/composables/useFieldValidate.md index 8219462..8aeee7c 100644 --- a/apps/docs/guide/composables/useFieldValidate.md +++ b/apps/docs/guide/composables/useFieldValidate.md @@ -1,8 +1,11 @@ --- outline: [2,3] --- -# useFieldValidate -> Used to validate a field against validators defined in a fields schema +# useFieldValidate +> Used to validate a field against validators defined in a field's schema +::: warning +This composable is deprecated, please use [`useValidation`](/guide/composables/useValidation) instead +::: ## Usage ```vue diff --git a/apps/docs/guide/composables/useLabelIcon.md b/apps/docs/guide/composables/useLabelIcon.md new file mode 100644 index 0000000..0917ebb --- /dev/null +++ b/apps/docs/guide/composables/useLabelIcon.md @@ -0,0 +1,34 @@ +--- +outline: [2,3] +--- +# useLabelIcon +> Determines which icon to display and the position to display it in + +## Usage +```vue + +``` + +## Arguments +### `iconDefinition` +::: details LabelIconDefinition type +```ts +type LabelIconDefinition = { + icon: string | ComponentPublicInstance; + position: 'left' | 'right'; +} +``` +::: +Either a string webfont class, a component or `LabelIconDefinition`. + +## Returns + +### `labelIcon` +Either the icon class or icon component as determined by the `labelIcon` property of a field schema. + +### `labelIconPosition` +Position of the label, defaults to `left`. diff --git a/apps/docs/guide/composables/useValidation.md b/apps/docs/guide/composables/useValidation.md new file mode 100644 index 0000000..cd7f97a --- /dev/null +++ b/apps/docs/guide/composables/useValidation.md @@ -0,0 +1,119 @@ +--- +outline: [2,3] +--- +# useValidation +> Used to validate a field against validators defined in a field's schema + +## Usage +::: code-group +```Vue [Vue] + +``` +```Vue [Vue TS] + +``` +::: + +## Arguments + +### `model` +Model object, as returned by the props + +### `field` +Field schema object, as returned by the props + +### `currentModelValue` +`Ref` of the current value from the field. Returned by [`useFormModel`](/guide/composables/useFormModel). + +### `formOptions` +Form options object, as returned by the props. + +### `emits` +Emit function as returned by `defineEmits()` + +### `isDisabled` +Whether the field is disabled, can be obtained from [`useFieldAttributes()`](/guide/composables/useFieldAttributes) + +### `isRequired` +Whether the field is required, can be obtained from [`useFieldAttributes()`](/guide/composables/useFieldAttributes) + +### `isReadonly` +Whether the field is readonly, can be obtained from [`useFieldAttributes()`](/guide/composables/useFieldAttributes) + +## Returns + +### `errors` +An array of errors for the current field. Will be auto-updated on every validation cycle. Must be cleared +manually when the value of a field has changed. + +### `validate` +A validation function, meant to be called when a validation has to take place. Used when a field is always validated +at the same moment and isn't affected by validation triggers, such as `'onChanged'` or `'onBlur'`. + +### `onChanged` +A wrapped validation function, only validates when `'onChanged'` validation is enabled. Should always be called if the value is changed, unless the field is unaffected by +validation triggers. + +### `onBlur` +A wrapped validation function, only validates when `'onBlur'` validation is enabled (which is the default behavior). Should always be called if the value is changed, unless the field is unaffected by +validation triggers. diff --git a/apps/docs/guide/customization/custom-components.md b/apps/docs/guide/customization/custom-components.md index 77f05f3..68f0b99 100644 --- a/apps/docs/guide/customization/custom-components.md +++ b/apps/docs/guide/customization/custom-components.md @@ -15,35 +15,21 @@ To create a field component you make use of different composables ([?](https://v get the behaviour you want the component to have. Different composables handle different functionality inside the field component. +:::tabs +== JavaScript Every component must at least use these composables to work properly: - [`useFieldEmits`](/guide/composables/useFieldEmits) - returns all events emitted by a field component; - [`useFieldProps`](/guide/composables/useFieldProps) - returns all props used by a field component; - [`useFormModel`](/guide/composables/useFormModel) - used to get the current model value for this field component. Optional: -- [`useFieldValidate`](/guide/composables/useFieldValidate) - used for validation of the field; +- [`useValidation`](/guide/composables/useValidation) - used for validation of the field; - [`useFieldAttributes`](/guide/composables/useFieldAttributes) - holds different dynamic field attributes like `required` and `readonly`. ### Basic example ::: code-group -```vue [template] - -``` + ```vue [script setup] ``` ::: + ### Advanced example For a more advanced example, you can take a look at the [`FieldSelect`](/guide/fields/FieldSelect) ([source](https://github.com/kevinkosterr/vue3-form-generator/blob/69cb6aeb8e8c82926ec3598e7d73be2d1146a3f2/src/fields/core/FieldSelect.vue)) component. ## Compatibility with validation ::: info If you want your component to be compatible with validation, you'll need to expose the `errors` value that is returned -by [`useFieldValidate`](/guide/composables/useFieldValidate) +by [`useValidation`](/guide/composables/useValidation) ::: ## Registering your component diff --git a/apps/docs/guide/form-generator/props.md b/apps/docs/guide/form-generator/props.md index 14e8c28..f67b8e9 100644 --- a/apps/docs/guide/form-generator/props.md +++ b/apps/docs/guide/form-generator/props.md @@ -12,9 +12,10 @@ outline: [ 2,3 ] | `idPrefix` | `string` | Prefix for all the generated ids in the form | ## `formOptions` -| Property | Type | Description | -|---------------|----------|------------------------------------------------------| -| `idPrefix` | `string` | Prefix for all the generated ids in the form | +| Property | Type | Default | Description | +|------------|--------------------------|--------|-----------------------------------------------------------------------------------------------------| +| `idPrefix` | `string` | | Prefix for all the generated ids in the form | +| `validate` | `'onChanged'` \| `'onBlur'` | `onBlur` | Method of validation, can be overwritten by individual fields. Can be either `onChanged` or `onBlur` | ## `model` Type: `Object` diff --git a/apps/docs/parts/customization/custom-components-template-example.md b/apps/docs/parts/customization/custom-components-template-example.md new file mode 100644 index 0000000..16f4308 --- /dev/null +++ b/apps/docs/parts/customization/custom-components-template-example.md @@ -0,0 +1,17 @@ +```vue [template] + +``` \ No newline at end of file diff --git a/apps/docs/parts/shared-field-properties.md b/apps/docs/parts/shared-field-properties.md index c857ba8..5db6a24 100644 --- a/apps/docs/parts/shared-field-properties.md +++ b/apps/docs/parts/shared-field-properties.md @@ -1,17 +1,19 @@ -| Property | Default | Type | Description | -|-------------|------------|---------------------------------------------|-------------------------------------------------------------------------------------------------| -| name | - | `string` | Name of the field | -| model | - | `string` | Key of model in the form schema model | -| label | - | `string` | Label for the field | -| type | - | `string` | Type of field, generally `input` if the field is an input. | -| inputType | - | `string` | Type of input, only required when `type === 'input'` | -| id | _computed_ | `string` | `id` of the field | -| visible | `true` | `Boolean \| Function` | Whether the field is visible, method will be passed the `model`, `field` and field component* | -| required | `false` | `Boolean \| Function` | Whether the field is required, method will be passed the `model`, `field` and field component* | -| readonly | `false` | `Boolean \| Function` | Whether the field is read only, method will be passed the `model`, `field` and field component* | -| disabled | `false` | `Boolean \| Function` | Whether the field is disabled, method will be passed the `model`, `field` and field component* | -| hint | - | `string \| Function` | Hint to display underneath the field, can be passed a method* | -| validator | _computed_ | `Array \| Function \| undefined` | A (list of) validator(s) to be validating the field against. | -| onValidated | - | `Function \| undefined` | Method to be called after validation has been completed. | +| Property | Default | Type | Description | +|-------------|-----------|------------------------------------------------------------|-------------------------------------------------------------------------------------------------| +| name | - | `string` | Name of the field | +| model | - | `string` | Key of model in the form schema model | +| label | - | `string` | Label for the field | +| labelIcon | - | `string \| ComponentPublicInstance \| LabelIconDefinition` | Label for the field | +| type | - | `string` | Type of field, generally `input` if the field is an input. | +| inputType | - | `string` | Type of input, only required when `type === 'input'` | +| id | _computed_ | `string` | `id` of the field | +| visible | `true` | `Boolean \| Function` | Whether the field is visible, method will be passed the `model`, `field` and field component* | +| required | `false` | `Boolean \| Function` | Whether the field is required, method will be passed the `model`, `field` and field component* | +| readonly | `false` | `Boolean \| Function` | Whether the field is read only, method will be passed the `model`, `field` and field component* | +| disabled | `false` | `Boolean \| Function` | Whether the field is disabled, method will be passed the `model`, `field` and field component* | +| hint | - | `string \| Function` | Hint to display underneath the field, can be passed a method* | +| validator | _computed_ | `Array \| Function \| undefined` | A (list of) validator(s) to be validating the field against. | +| validate | `onBlur` | `'onChanged'` \| `'onBlur'` | Method of validation for the field. | +| onValidated | - | `Function \| undefined` | Method to be called after validation has been completed. | _*_ see [determineDynamicAttribute()](/guide/mixins/abstractField#determinedynamicattribute) for more information. \ No newline at end of file diff --git a/index.html b/index.html index 3a9040a..cf0b9e3 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,7 @@ + Vite App diff --git a/package.json b/package.json index dbc5e92..9cda452 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dev": "vite", "dev:sass": "sass --watch src/scss/themes:apps/playground/css/", "test": "vitest", + "test:ui": "vitest --ui", "build": "vite build && sass src/scss/themes/:dist/themes/", "preview": "vite preview", "docs:dev": "vitepress dev apps/docs", @@ -55,6 +56,7 @@ "@stylistic/eslint-plugin": "^2.8.0", "@typescript-eslint/parser": "^8.13.0", "@vitejs/plugin-vue": "^5.1.3", + "@vitest/ui": "^3.2.4", "@vue/test-utils": "^2.4.6", "clipboard": "^2.0.11", "eslint": "^9.10.0", @@ -70,6 +72,7 @@ "vite-plugin-dts": "^4.3.0", "vitepress": "^1.6.3", "vitepress-plugin-group-icons": "^1.5.5", + "vitepress-plugin-tabs": "^0.7.1", "vitest": "^2.1.1", "vue": "^3.5.6", "vue-eslint-parser": "^9.4.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 65c15ee..44bbca6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,12 +5,15 @@ settings: excludeLinksFromLockfile: false overrides: - '@octokit/request-error@>=6.0.0 <6.1.7': '>=6.1.7' + '@eslint/plugin-kit@<0.3.3': '>=0.3.3' '@octokit/endpoint@>=10.0.0 <10.1.3': '>=10.1.3' + '@octokit/plugin-paginate-rest@>=9.3.0-beta.1 <11.4.1': '>=11.4.1' + '@octokit/request-error@>=6.0.0 <6.1.7': '>=6.1.7' + '@octokit/request@>=9.0.0-beta.1 <9.2.1': '>=9.2.1' + brace-expansion: '>=2.0.2' esbuild@<=0.24.2: '>=0.25.0' + form-data@>=4.0.0 <4.0.4: '>=4.0.4' vitest@>=2.0.0 <2.1.9: '>=2.1.9' - '@octokit/request@>=9.0.0-beta.1 <9.2.1': '>=9.2.1' - '@octokit/plugin-paginate-rest@>=9.3.0-beta.1 <11.4.1': '>=11.4.1' importers: @@ -38,6 +41,9 @@ importers: '@vitejs/plugin-vue': specifier: ^5.1.3 version: 5.2.1(vite@5.4.19(sass@1.82.0)(terser@5.37.0))(vue@3.5.13(typescript@5.7.2)) + '@vitest/ui': + specifier: ^3.2.4 + version: 3.2.4(vitest@3.1.3) '@vue/test-utils': specifier: ^2.4.6 version: 2.4.6 @@ -83,9 +89,12 @@ importers: vitepress-plugin-group-icons: specifier: ^1.5.5 version: 1.5.5(markdown-it@14.1.0)(vite@5.4.19(sass@1.82.0)(terser@5.37.0)) + vitepress-plugin-tabs: + specifier: ^0.7.1 + version: 0.7.1(vitepress@1.6.3(@algolia/client-search@5.25.0)(postcss@8.4.49)(sass@1.82.0)(search-insights@2.17.3)(terser@5.37.0)(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2)) vitest: specifier: '>=2.1.9' - version: 3.1.3(jsdom@25.0.1)(sass@1.82.0)(terser@5.37.0) + version: 3.1.3(@vitest/ui@3.2.4)(jsdom@25.0.1)(sass@1.82.0)(terser@5.37.0) vue: specifier: ^3.5.6 version: 3.5.13(typescript@5.7.2) @@ -388,6 +397,10 @@ packages: resolution: {integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.15.1': + resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.9.1': resolution: {integrity: sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -404,8 +417,8 @@ packages: resolution: {integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.2.4': - resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==} + '@eslint/plugin-kit@0.3.4': + resolution: {integrity: sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@humanfs/core@0.19.1': @@ -648,6 +661,9 @@ packages: resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} engines: {node: '>=12'} + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + '@rollup/pluginutils@5.1.3': resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} engines: {node: '>=14.0.0'} @@ -957,6 +973,9 @@ packages: '@vitest/pretty-format@3.1.3': resolution: {integrity: sha512-i6FDiBeJUGLDKADw2Gb01UtUNb12yyXAqC/mmRWuYl+m/U9GS7s8us5ONmGkGpUUo7/iAYzI2ePVfOZTYvUifA==} + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/runner@3.1.3': resolution: {integrity: sha512-Tae+ogtlNfFei5DggOsSUvkIaSuVywujMj6HzR97AHK6XK8i3BuVyIifWAm/sE3a15lF5RH9yQIrbXYuo0IFyA==} @@ -966,9 +985,17 @@ packages: '@vitest/spy@3.1.3': resolution: {integrity: sha512-x6w+ctOEmEXdWaa6TO4ilb7l9DxPR5bwEb6hILKuxfU1NqWT2mpJD9NJN7t3OTfxmVlOMrvtoFJGdgyzZ605lQ==} + '@vitest/ui@3.2.4': + resolution: {integrity: sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA==} + peerDependencies: + vitest: 3.2.4 + '@vitest/utils@3.1.3': resolution: {integrity: sha512-2Ltrpht4OmHO9+c/nmHtF09HWiyWdworqnHIwjfvDyWjuwKbdkcS9AnhsDn+8E2RM4x++foD1/tNuLPVvWG1Rg==} + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@volar/language-core@2.4.10': resolution: {integrity: sha512-hG3Z13+nJmGaT+fnQzAkS0hjJRa2FCeqZt6Bd+oGNhUkQ+mTFsDETg5rqUTxyzIh5pSOGY7FHCWUS8G82AzLCA==} @@ -1190,8 +1217,9 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@3.0.1: + resolution: {integrity: sha512-vjtV3hiLqYDNRoiAv0zC4QaGAMPomEoq83PRmYIofPswwZurCeWR5LByXm7SyoL0Zh5+2z0+HC7jG8gSZJUh0w==} + engines: {node: '>= 16'} before-after-hook@3.0.2: resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} @@ -1205,11 +1233,9 @@ packages: bottleneck@2.19.5: resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@4.0.1: + resolution: {integrity: sha512-YClrbvTCXGe70pU2JiEiPLYXO9gQkyxYeKpJIQHVS/gOs6EWMQP2RYBwjFLNT322Ji8TOC3IMPfsYCedNpzKfA==} + engines: {node: '>= 18'} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -1222,6 +1248,10 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1322,9 +1352,6 @@ packages: computeds@0.0.1: resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -1449,6 +1476,10 @@ packages: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + duplexer2@0.1.4: resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} @@ -1491,9 +1522,25 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + esbuild@0.25.4: resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} engines: {node: '>=18'} @@ -1622,6 +1669,9 @@ packages: picomatch: optional: true + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + figures@2.0.0: resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} engines: {node: '>=4'} @@ -1661,6 +1711,9 @@ packages: flatted@3.3.2: resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + focus-trap@7.6.4: resolution: {integrity: sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==} @@ -1668,8 +1721,8 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} - form-data@4.0.1: - resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} engines: {node: '>= 6'} from2@2.3.0: @@ -1699,6 +1752,14 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -1749,6 +1810,10 @@ packages: good-listener@1.2.2: resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} @@ -1771,6 +1836,14 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -2059,6 +2132,9 @@ packages: loupe@3.1.3: resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + loupe@3.2.0: + resolution: {integrity: sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -2093,6 +2169,10 @@ packages: maska@3.1.1: resolution: {integrity: sha512-68ZJfZ6/YANwv7CufbQmcCNoHdJnIRxuQgZtSFZe5ltlmZ15ZdA01siUGLh9EfaUX65DN0l/A7g+o2xjTICeGQ==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + mdast-util-to-hast@13.2.0: resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} @@ -2179,6 +2259,10 @@ packages: mlly@1.7.4: resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2656,6 +2740,10 @@ packages: resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==} engines: {node: '>=6'} + sirv@3.0.1: + resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + engines: {node: '>=18'} + skin-tone@2.0.0: resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} engines: {node: '>=8'} @@ -2835,6 +2923,10 @@ packages: resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.14: + resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + engines: {node: '>=12.0.0'} + tinypool@1.0.2: resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -2858,6 +2950,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + tough-cookie@5.0.0: resolution: {integrity: sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==} engines: {node: '>=16'} @@ -3040,6 +3136,12 @@ packages: markdown-it: '>=14' vite: '>=3' + vitepress-plugin-tabs@0.7.1: + resolution: {integrity: sha512-jxJvsicxnMSIYX9b8mAFLD2nwyKUcMO10dEt4nDSbinZhM8cGvAmMFOHPdf6TBX6gYZRl+/++/iYHtoM14fERQ==} + peerDependencies: + vitepress: ^1.0.0 + vue: ^3.5.0 + vitepress@1.6.3: resolution: {integrity: sha512-fCkfdOk8yRZT8GD9BFqusW3+GggWYZ/rYncOfmgcDtP3ualNHCAg+Robxp2/6xfH1WwPHtGpPwv7mbA3qomtBw==} hasBin: true @@ -3461,6 +3563,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/core@0.15.1': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/core@0.9.1': dependencies: '@types/json-schema': 7.0.15 @@ -3483,8 +3589,9 @@ snapshots: '@eslint/object-schema@2.1.5': {} - '@eslint/plugin-kit@0.2.4': + '@eslint/plugin-kit@0.3.4': dependencies: + '@eslint/core': 0.15.1 levn: 0.4.1 '@humanfs/core@0.19.1': {} @@ -3748,6 +3855,8 @@ snapshots: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 + '@polka/url@1.0.0-next.29': {} + '@rollup/pluginutils@5.1.3(rollup@4.28.1)': dependencies: '@types/estree': 1.0.6 @@ -4108,6 +4217,10 @@ snapshots: dependencies: tinyrainbow: 2.0.0 + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + '@vitest/runner@3.1.3': dependencies: '@vitest/utils': 3.1.3 @@ -4123,12 +4236,29 @@ snapshots: dependencies: tinyspy: 3.0.2 + '@vitest/ui@3.2.4(vitest@3.1.3)': + dependencies: + '@vitest/utils': 3.2.4 + fflate: 0.8.2 + flatted: 3.3.3 + pathe: 2.0.3 + sirv: 3.0.1 + tinyglobby: 0.2.14 + tinyrainbow: 2.0.0 + vitest: 3.1.3(@vitest/ui@3.2.4)(jsdom@25.0.1)(sass@1.82.0)(terser@5.37.0) + '@vitest/utils@3.1.3': dependencies: '@vitest/pretty-format': 3.1.3 loupe: 3.1.3 tinyrainbow: 2.0.0 + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.0 + tinyrainbow: 2.0.0 + '@volar/language-core@2.4.10': dependencies: '@volar/source-map': 2.4.10 @@ -4370,7 +4500,7 @@ snapshots: asynckit@0.4.0: {} - balanced-match@1.0.2: {} + balanced-match@3.0.1: {} before-after-hook@3.0.2: {} @@ -4380,14 +4510,9 @@ snapshots: bottleneck@2.19.5: {} - brace-expansion@1.1.11: + brace-expansion@4.0.1: dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 + balanced-match: 3.0.1 braces@3.0.3: dependencies: @@ -4397,6 +4522,11 @@ snapshots: cac@6.7.14: {} + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + callsites@3.1.0: {} ccount@2.0.1: {} @@ -4502,8 +4632,6 @@ snapshots: computeds@0.0.1: {} - concat-map@0.0.1: {} - confbox@0.1.8: {} confbox@0.2.2: {} @@ -4606,6 +4734,12 @@ snapshots: dependencies: is-obj: 2.0.0 + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + duplexer2@0.1.4: dependencies: readable-stream: 2.3.8 @@ -4642,8 +4776,23 @@ snapshots: dependencies: is-arrayish: 0.2.1 + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + es-module-lexer@1.7.0: {} + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + esbuild@0.25.4: optionalDependencies: '@esbuild/aix-ppc64': 0.25.4 @@ -4718,7 +4867,7 @@ snapshots: '@eslint/core': 0.9.1 '@eslint/eslintrc': 3.2.0 '@eslint/js': 9.16.0 - '@eslint/plugin-kit': 0.2.4 + '@eslint/plugin-kit': 0.3.4 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.1 @@ -4834,6 +4983,8 @@ snapshots: optionalDependencies: picomatch: 4.0.2 + fflate@0.8.2: {} + figures@2.0.0: dependencies: escape-string-regexp: 1.0.5 @@ -4873,6 +5024,8 @@ snapshots: flatted@3.3.2: {} + flatted@3.3.3: {} + focus-trap@7.6.4: dependencies: tabbable: 6.2.0 @@ -4882,10 +5035,12 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - form-data@4.0.1: + form-data@4.0.4: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 mime-types: 2.1.35 from2@2.3.0: @@ -4914,6 +5069,24 @@ snapshots: get-caller-file@2.0.5: {} + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + get-stream@6.0.1: {} get-stream@7.0.1: {} @@ -4972,6 +5145,8 @@ snapshots: dependencies: delegate: 3.2.0 + gopd@1.2.0: {} + graceful-fs@4.2.10: {} graceful-fs@4.2.11: {} @@ -4991,6 +5166,12 @@ snapshots: has-flag@4.0.0: {} + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -5165,7 +5346,7 @@ snapshots: cssstyle: 4.1.0 data-urls: 5.0.0 decimal.js: 10.4.3 - form-data: 4.0.1 + form-data: 4.0.4 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 @@ -5274,6 +5455,8 @@ snapshots: loupe@3.1.3: {} + loupe@3.2.0: {} + lru-cache@10.4.3: {} lru-cache@6.0.0: @@ -5314,6 +5497,8 @@ snapshots: maska@3.1.1: {} + math-intrinsics@1.1.0: {} + mdast-util-to-hast@13.2.0: dependencies: '@types/hast': 3.0.4 @@ -5368,19 +5553,19 @@ snapshots: minimatch@3.0.8: dependencies: - brace-expansion: 1.1.11 + brace-expansion: 4.0.1 minimatch@3.1.2: dependencies: - brace-expansion: 1.1.11 + brace-expansion: 4.0.1 minimatch@9.0.1: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 4.0.1 minimatch@9.0.5: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 4.0.1 minimist@1.2.8: {} @@ -5404,6 +5589,8 @@ snapshots: pkg-types: 1.3.1 ufo: 1.5.4 + mrmime@2.0.1: {} + ms@2.1.3: {} muggle-string@0.4.1: {} @@ -5835,6 +6022,12 @@ snapshots: figures: 2.0.0 pkg-conf: 2.1.0 + sirv@3.0.1: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + skin-tone@2.0.0: dependencies: unicode-emoji-modifier-base: 1.0.0 @@ -6004,6 +6197,11 @@ snapshots: fdir: 6.4.4(picomatch@4.0.2) picomatch: 4.0.2 + tinyglobby@0.2.14: + dependencies: + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + tinypool@1.0.2: {} tinyrainbow@2.0.0: {} @@ -6020,6 +6218,8 @@ snapshots: dependencies: is-number: 7.0.0 + totalist@3.0.1: {} + tough-cookie@5.0.0: dependencies: tldts: 6.1.66 @@ -6188,6 +6388,11 @@ snapshots: transitivePeerDependencies: - supports-color + vitepress-plugin-tabs@0.7.1(vitepress@1.6.3(@algolia/client-search@5.25.0)(postcss@8.4.49)(sass@1.82.0)(search-insights@2.17.3)(terser@5.37.0)(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2)): + dependencies: + vitepress: 1.6.3(@algolia/client-search@5.25.0)(postcss@8.4.49)(sass@1.82.0)(search-insights@2.17.3)(terser@5.37.0)(typescript@5.7.2) + vue: 3.5.13(typescript@5.7.2) + vitepress@1.6.3(@algolia/client-search@5.25.0)(postcss@8.4.49)(sass@1.82.0)(search-insights@2.17.3)(terser@5.37.0)(typescript@5.7.2): dependencies: '@docsearch/css': 3.8.2 @@ -6237,7 +6442,7 @@ snapshots: - typescript - universal-cookie - vitest@3.1.3(jsdom@25.0.1)(sass@1.82.0)(terser@5.37.0): + vitest@3.1.3(@vitest/ui@3.2.4)(jsdom@25.0.1)(sass@1.82.0)(terser@5.37.0): dependencies: '@vitest/expect': 3.1.3 '@vitest/mocker': 3.1.3(vite@5.4.19(sass@1.82.0)(terser@5.37.0)) @@ -6261,6 +6466,7 @@ snapshots: vite-node: 3.1.3(sass@1.82.0)(terser@5.37.0) why-is-node-running: 2.3.0 optionalDependencies: + '@vitest/ui': 3.2.4(vitest@3.1.3) jsdom: 25.0.1 transitivePeerDependencies: - less diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c904585..97781f2 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,7 +1,10 @@ overrides: - '@octokit/request-error@>=6.0.0 <6.1.7': '>=6.1.7' + '@eslint/plugin-kit@<0.3.3': '>=0.3.3' '@octokit/endpoint@>=10.0.0 <10.1.3': '>=10.1.3' + '@octokit/plugin-paginate-rest@>=9.3.0-beta.1 <11.4.1': '>=11.4.1' + '@octokit/request-error@>=6.0.0 <6.1.7': '>=6.1.7' + '@octokit/request@>=9.0.0-beta.1 <9.2.1': '>=9.2.1' + brace-expansion: '>=2.0.2' esbuild@<=0.24.2: '>=0.25.0' + form-data@>=4.0.0 <4.0.4: '>=4.0.4' vitest@>=2.0.0 <2.1.9: '>=2.1.9' - '@octokit/request@>=9.0.0-beta.1 <9.2.1': '>=9.2.1' - '@octokit/plugin-paginate-rest@>=9.3.0-beta.1 <11.4.1': '>=11.4.1' diff --git a/src/FormGenerator.vue b/src/FormGenerator.vue index 19e0934..141579f 100644 --- a/src/FormGenerator.vue +++ b/src/FormGenerator.vue @@ -51,7 +51,9 @@ const props = withDefaults(defineProps(), { enctype: 'application/x-www-form-urlencoded', id: '', idPrefix: '', // Kept for compatibility reasons. - options: () => ({}) + options: () => ({ + validate: 'onBlur' // Always validate onBlur by default. + }) }) type FormGroupInstance = ComponentPublicInstance> diff --git a/src/FormGroup.vue b/src/FormGroup.vue index 4efbd2e..a47ea0e 100644 --- a/src/FormGroup.vue +++ b/src/FormGroup.vue @@ -1,8 +1,12 @@