1
0
Fork 0
mirror of synced 2025-04-03 13:23:34 +03:00

Compare commits

...

32 commits

Author SHA1 Message Date
Kirill Zaytsev
a4375f0a22 chore(release): 0.8.3 2024-12-06 17:39:32 +04:00
Kirill Zaytsev
119286a524 chore: Removed dist from git 2024-12-06 17:38:46 +04:00
Kirill Zaytsev
cbe80e3de4 feat: Updated package.json manifest 2024-12-06 17:38:03 +04:00
Kirill Zaytsev
bfeba566d9 chore(release): 0.8.2 2023-12-28 13:55:22 +04:00
Kirill Zaytsev
eda7a1d79d feat: Added web-types declaration 2023-12-28 13:55:15 +04:00
Kirill Zaytsev
12235e8307 chore(release): 0.8.1 2023-12-28 13:11:23 +04:00
Kirill Zaytsev
92a3f8cc60 fix: build 2023-12-28 13:11:07 +04:00
Kirill Zaytsev
497b2a1967 chore(release): 0.8.0 2023-12-28 12:53:00 +04:00
Zaytsev Kirill
fa4bc2683c chore: Removed unused dependency 2023-12-28 12:48:51 +04:00
Zaytsev Kirill
b83a429117 chore!: Old names of FormularioField & FormularioFieldGroup no longer available 2023-12-28 12:48:51 +04:00
Zaytsev Kirill
0d2a5329db refactor: merge util removed due it's no longer required 2023-12-28 12:48:51 +04:00
Kirill Zaytsev
dfc6557bc6 feat: Components conststructors are exposed as external API, added TypeScript declarations 2023-12-28 12:48:51 +04:00
Kirill Zaytsev
6224b40e02 chore: node version in docker-compose rised to v16 2023-12-28 12:48:51 +04:00
Kirill Zaytsev
1e456627a1 chore: node-sass updated to v9.x.x 2023-12-28 12:48:51 +04:00
dependabot[bot]
f204f9b672 chore(deps): bump elliptic from 6.5.3 to 6.5.4
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4)

---
updated-dependencies:
- dependency-name: elliptic
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-13 18:01:06 +03:00
dependabot[bot]
0b20bbbd95 chore(deps): bump trim-off-newlines from 1.0.1 to 1.0.3
Bumps [trim-off-newlines](https://github.com/stevemao/trim-off-newlines) from 1.0.1 to 1.0.3.
- [Release notes](https://github.com/stevemao/trim-off-newlines/releases)
- [Commits](https://github.com/stevemao/trim-off-newlines/compare/v1.0.1...v1.0.3)

---
updated-dependencies:
- dependency-name: trim-off-newlines
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-13 17:41:06 +03:00
dependabot[bot]
8c1e979871 chore(deps): bump shelljs from 0.8.4 to 0.8.5
Bumps [shelljs](https://github.com/shelljs/shelljs) from 0.8.4 to 0.8.5.
- [Release notes](https://github.com/shelljs/shelljs/releases)
- [Changelog](https://github.com/shelljs/shelljs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/shelljs/shelljs/compare/v0.8.4...v0.8.5)

---
updated-dependencies:
- dependency-name: shelljs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-13 17:38:48 +03:00
dependabot[bot]
90f2439692 chore(deps): bump node-fetch from 2.6.1 to 2.6.7
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-13 17:38:35 +03:00
dependabot[bot]
78b1ac6da5 chore(deps): bump dns-packet from 1.3.1 to 1.3.4
Bumps [dns-packet](https://github.com/mafintosh/dns-packet) from 1.3.1 to 1.3.4.
- [Release notes](https://github.com/mafintosh/dns-packet/releases)
- [Changelog](https://github.com/mafintosh/dns-packet/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mafintosh/dns-packet/compare/v1.3.1...v1.3.4)

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-13 16:56:49 +03:00
dependabot[bot]
877a672ce9 chore(deps): bump tmpl from 1.0.4 to 1.0.5
Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/daaku/nodejs-tmpl/releases)
- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5)

---
updated-dependencies:
- dependency-name: tmpl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-13 16:56:40 +03:00
dependabot[bot]
593af7efc8 chore(deps): bump follow-redirects from 1.11.0 to 1.14.8
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.11.0 to 1.14.8.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.11.0...v1.14.8)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-13 16:56:06 +03:00
dependabot[bot]
674449707b chore(deps): bump minimist from 1.2.5 to 1.2.6
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-13 16:55:15 +03:00
dependabot[bot]
e3e7aea10d chore(deps): bump eventsource from 1.0.7 to 1.1.1
Bumps [eventsource](https://github.com/EventSource/eventsource) from 1.0.7 to 1.1.1.
- [Release notes](https://github.com/EventSource/eventsource/releases)
- [Changelog](https://github.com/EventSource/eventsource/blob/master/HISTORY.md)
- [Commits](https://github.com/EventSource/eventsource/compare/v1.0.7...v1.1.1)

---
updated-dependencies:
- dependency-name: eventsource
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-13 16:55:02 +03:00
dependabot[bot]
b3849e45f3 chore(deps): bump jsdom from 16.4.0 to 16.7.0
Bumps [jsdom](https://github.com/jsdom/jsdom) from 16.4.0 to 16.7.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/master/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/16.4.0...16.7.0)

---
updated-dependencies:
- dependency-name: jsdom
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-13 16:54:30 +03:00
1on
0b5607bbbe chore(release): 0.7.3 2021-11-11 11:41:23 +03:00
Kruglov Kirill
2f3a63b012
Merge pull request #38 from cmath10/fix-tostring-in-validators
fix: Fixed toString calls in validators
2021-11-11 11:39:38 +03:00
Zaytsev Kirill
da56b04213 fix: Fixed toString calls in validators 2021-11-11 11:28:12 +03:00
1on
76dec48d64 chore(release): 0.7.2 2021-10-21 12:56:11 +03:00
Kruglov Kirill
29975e3ddb
Merge pull request #37 from cmath10/fix-blob-cloning
fix: Blob objects are no longer cloned
2021-10-21 12:50:32 +03:00
Zaytsev Kirill
67dba981a1 fix: Blob objects are no longer cloned 2021-10-21 12:45:43 +03:00
1on
bff166a396 chore(release): 0.7.1 2021-09-30 13:51:30 +03:00
1on
8e36a9f59d fix: Build 2021-09-30 13:51:12 +03:00
34 changed files with 2680 additions and 4339 deletions

View file

@ -1,30 +1,27 @@
module.exports = {
root: true,
parserOptions: {
parser: '@typescript-eslint/parser',
sourceType: 'module',
},
plugins: ['@typescript-eslint'],
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
extends: [
'standard',
'@vue/standard',
'@vue/typescript',
'plugin:@typescript-eslint/recommended',
'plugin:vue/recommended',
],
env: {
browser: true,
},
parserOptions: {
parser: '@typescript-eslint/parser',
},
plugins: [
'@typescript-eslint',
'vue',
],
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:vue/recommended',
],
rules: {
'@typescript-eslint/camelcase': ['error', {
allow: ['^__Formulario'],
}],
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'off', // @TODO
'@typescript-eslint/no-unused-vars': ['error'], // @TODO

11
.gitignore vendored
View file

@ -1,11 +1,16 @@
node_modules
coverage
.cache
.DS_Store
.idea
.vscode
coverage
dist/
node_modules
*.sublime-project
*.sublime-workspace
*.dev.tale.vue
*.dev.stories.js
storybook-static
storybook-static
.npmrc

View file

@ -2,6 +2,62 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [0.8.3](https://github.com/retailcrm/vue-formulario/compare/v0.8.2...v0.8.3) (2024-12-06)
### Features
* Updated package.json manifest ([cbe80e3](https://github.com/retailcrm/vue-formulario/commit/cbe80e3de498732af8db34f0846cc92d977d9420))
### [0.8.2](https://github.com/retailcrm/vue-formulario/compare/v0.8.1...v0.8.2) (2023-12-28)
### Features
* Added web-types declaration ([eda7a1d](https://github.com/retailcrm/vue-formulario/commit/eda7a1d79d98e4ccd76e67bc93c1bf8dc5249e67))
### [0.8.1](https://github.com/retailcrm/vue-formulario/compare/v0.8.0...v0.8.1) (2023-12-28)
### Fixes
* build ([92a3f8c](https://github.com/retailcrm/vue-formulario/commit/92a3f8cc60fdfb1f7588b281febcc833b17d3521))
## [0.8.0](https://github.com/retailcrm/vue-formulario/compare/v0.7.3...v0.8.0) (2023-12-28)
### ⚠ BREAKING CHANGES
* Old names of FormularioField & FormularioFieldGroup no longer available
### Features
* Components conststructors are exposed as external API, added TypeScript declarations ([dfc6557](https://github.com/retailcrm/vue-formulario/commit/dfc6557bc632489daeb8f4ae44ad208f6c6a9997))
* Old names of FormularioField & FormularioFieldGroup no longer available ([b83a429](https://github.com/retailcrm/vue-formulario/commit/b83a42911749272c9c8bd35c4ea10f687c5d8821))
### [0.7.3](https://github.com/retailcrm/vue-formulario/compare/v0.7.2...v0.7.3) (2021-11-11)
### Fixes
* Fixed toString calls in validators ([da56b04](https://github.com/retailcrm/vue-formulario/commit/da56b04213b6ebc3d001a273b26a350a59e0382b))
### [0.7.2](https://github.com/retailcrm/vue-formulario/compare/v0.7.1...v0.7.2) (2021-10-21)
### Fixes
* Blob objects are no longer cloned ([67dba98](https://github.com/retailcrm/vue-formulario/commit/67dba981a15b04a84512de277f633d0f7d19d543))
### [0.7.1](https://github.com/retailcrm/vue-formulario/compare/v0.7.0...v0.7.1) (2021-09-30)
### Fixes
* Build ([8e36a9f](https://github.com/retailcrm/vue-formulario/commit/8e36a9f59dc21d0efc4f3dfe97fe992c204ee3e0))
## [0.7.0](https://github.com/retailcrm/vue-formulario/compare/v0.6.3...v0.7.0) (2021-09-30)

View file

@ -9,9 +9,7 @@ export default {
input: 'src/index.ts',
output: [{
name: 'Formulario',
exports: 'default',
globals: {
'is-plain-object': 'isPlainObject',
'is-url': 'isUrl',
vue: 'Vue',
'vue-property-decorator': 'vuePropertyDecorator',

View file

@ -11,10 +11,8 @@ export default {
input: 'src/index.ts',
output: {
name: 'VueFormulario',
exports: 'default',
format: 'iife',
globals: {
'is-plain-object': 'isPlainObject',
'is-url': 'isUrl',
vue: 'Vue',
'vue-property-decorator': 'vuePropertyDecorator',
@ -30,7 +28,7 @@ export default {
vue({ css: true, compileTemplate: true }),
alias({ entries: [{ find: /^@\/(.+)/, replacement: './$1' }] }),
commonjs(),
internal(['is-plain-object', 'is-url', 'vue-property-decorator']),
internal(['is-url', 'vue-property-decorator']),
terser(),
]
}

1531
dist/formulario.esm.js vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

1538
dist/formulario.umd.js vendored

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
version: '3.6'
services:
node:
image: node:12-alpine
image: node:16-alpine
user: node
volumes:
- ./:/var/www/vue-formulario

94
index.d.ts vendored Normal file
View file

@ -0,0 +1,94 @@
// noinspection JSUnusedGlobalSymbols
import type { Vue } from 'vue/types/vue'
import type { PluginObject } from 'vue/types/plugin'
import type { DefineComponent } from './types/vue'
import type { FormularioFormConstructor } from './types/form'
import type {
ModelGetConverter,
ModelSetConverter,
ValidationBehaviour,
UnregisterBehaviour,
} from './types/field'
import type {
ValidationMessageFn,
ValidationMessageI18NFn,
ValidationRuleFn,
Violation,
} from './types/validation'
import type { Options } from './types/plugin'
declare const FormularioForm: FormularioFormConstructor
export { FormularioForm }
declare const FormularioField: DefineComponent<{
name: string;
value?: unknown;
validation?: string|any[];
/** Defaults to 'demand' */
validationBehavior?: ValidationBehaviour;
validationRules?: Record<string, ValidationRuleFn>;
validationMessages?: Record<string, ValidationMessageI18NFn|string>;
errorsDisabled?: boolean;
modelGetConverter?: ModelGetConverter;
modelSetConverter?: ModelSetConverter;
/** Defaults to 'none' */
unregisterBehavior?: UnregisterBehaviour;
tag?: string;
}, {
runValidation(): Promise<Violation[]>;
hasValidationErrors (): Promise<boolean>;
/** @internal */
resetValidation(): void;
}>
export { FormularioField }
declare class Formulario {
public validationRules: Record<string, ValidationRuleFn>;
public validationMessages: Record<string, ValidationMessageI18NFn|string>;
constructor (options?: Options);
/** Given a set of options, apply them to the pre-existing options. */
public extend (extendWith: Options): Formulario;
public runValidation (id: string): Promise<Record<string, Violation[]>>;
public resetValidation (id: string): void;
/** Used by forms instances to add themselves into a registry */
public register (id: string, form: InstanceType<FormularioFormConstructor>): void;
/** Used by forms instances to remove themselves from a registry */
public unregister (id: string): void;
/** Get validation rules by merging any passed in with global rules. */
public getRules (extendWith: Record<string, ValidationRuleFn> = {}): Record<string, ValidationRuleFn>;
/** Get validation messages by merging any passed in with global messages. */
public getMessages (
vm: Vue,
extendWith: Record<string, ValidationMessageI18NFn|string>
): Record<string, ValidationMessageFn>;
}
export { Formulario }
declare module 'vue/types/vue' {
interface Vue {
readonly $formulario: Formulario;
}
}
declare const VueFormulario: PluginObject<Options> & {
Formulario: Formulario,
}
export default VueFormulario

View file

@ -1,6 +1,6 @@
{
"name": "@retailcrm/vue-formulario",
"version": "0.7.0",
"version": "0.8.3",
"license": "MIT",
"author": "RetailDriverLLC <integration@retailcrm.ru>",
"main": "dist/formulario.umd.js",
@ -9,12 +9,22 @@
"./sfc": "src/index.ts"
},
"unpkg": "dist/formulario.min.js",
"web-types": "web-types.json",
"files": [
"dist",
"types",
"CHANGELOG.md",
"LICENSE.txt",
"README.md"
],
"dependencies": {
"is-plain-object": "^3.0.0",
"is-url": "^1.2.4",
"vue-class-component": "^7.2.3",
"vue-property-decorator": "^8.4.2"
},
"peerDependencies": {
"vue": "^2.6"
},
"bugs": {
"url": "https://github.com/retailcrm/vue-formulario/issues"
},
@ -24,7 +34,7 @@
"build:iife": "rollup --config build/rollup.iife.config.js --format iife --file dist/formulario.min.js",
"build:size": "gzip -c dist/formulario.esm.js | wc -c",
"build:umd": "rollup --config build/rollup.config.js --format umd --file dist/formulario.umd.js",
"lint": "vue-cli-service lint",
"lint": "eslint --ext .js,.mjs,.ts,.vue",
"release": "standard-version",
"release:minor": "standard-version --release-as minor",
"release:patch": "standard-version --release-as patch",
@ -52,32 +62,28 @@
"@storybook/vue": "^6.0.26",
"@types/is-url": "^1.2.28",
"@types/jest": "^26.0.14",
"@typescript-eslint/eslint-plugin": "^2.26.0",
"@typescript-eslint/parser": "^2.26.0",
"@typescript-eslint/eslint-plugin": "^6.16.0",
"@typescript-eslint/parser": "^6.16.0",
"@vue/cli-plugin-babel": "^4.3.1",
"@vue/cli-plugin-eslint": "^4.3.1",
"@vue/cli-plugin-typescript": "^4.5.7",
"@vue/cli-service": "^4.5.4",
"@vue/component-compiler-utils": "^3.1.2",
"@vue/eslint-config-standard": "^5.1.2",
"@vue/eslint-config-typescript": "^5.0.2",
"@vue/test-utils": "^1.0.2",
"autoprefixer": "^9.7.6",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^25.5.1",
"bootstrap-scss": "^4.5.2",
"eslint": "^5.16.0",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-node": "^8.0.1",
"eslint-plugin-promise": "^4.1.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^5.2.3",
"eslint": "^8.56.0",
"eslint-config-standard": "^17.1.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-vue": "^9.19.2",
"flush-promises": "^1.0.2",
"jest": "^26.5.2",
"jest-vue-preprocessor": "^1.7.1",
"node-sass": "^4.14.1",
"node-sass": "^9.0.0",
"rollup": "^1.32.1",
"rollup-plugin-auto-external": "^2.0.0",
"rollup-plugin-internal": "^1.0.4",
@ -88,7 +94,7 @@
"sass-loader": "^10.0.3",
"standard-version": "^9.3.0",
"ts-jest": "^26.4.1",
"typescript": "~3.9.3",
"typescript": "^4.9.5",
"vue": "^2.6.11",
"vue-cli-plugin-storybook": "^1.3.0",
"vue-jest": "^3.0.5",

View file

@ -1,33 +1,26 @@
import merge from '@/utils/merge'
import validationRules from '@/validation/rules'
import validationMessages from '@/validation/messages'
import type { FormularioFormConstructor } from '../types/form'
import {
import type {
ValidationContext,
ValidationRuleFn,
ValidationMessageFn,
ValidationMessageI18NFn,
Violation,
} from '@/validation/validator'
} from '../types/validation'
import { FormularioForm } from '@/types'
import type { Options } from '../types/plugin'
export interface FormularioOptions {
validationRules?: Record<string, ValidationRuleFn>;
validationMessages?: Record<string, ValidationMessageI18NFn|string>;
}
import validationRules from '@/validation/rules'
import validationMessages from '@/validation/messages'
/**
* The base formulario library.
*/
export default class Formulario {
public validationRules: Record<string, ValidationRuleFn> = {}
public validationMessages: Record<string, ValidationMessageI18NFn|string> = {}
private readonly registry: Map<string, FormularioForm>
private readonly _registry: Map<string, InstanceType<FormularioFormConstructor>>
public constructor (options?: FormularioOptions) {
this.registry = new Map()
public constructor (options?: Options) {
this._registry = new Map()
this.validationRules = validationRules
this.validationMessages = validationMessages
@ -38,31 +31,31 @@ export default class Formulario {
/**
* Given a set of options, apply them to the pre-existing options.
*/
public extend (extendWith: FormularioOptions): Formulario {
public extend (extendWith: Options): Formulario {
if (typeof extendWith === 'object') {
this.validationRules = merge(this.validationRules, extendWith.validationRules || {})
this.validationMessages = merge(this.validationMessages, extendWith.validationMessages || {})
this.validationRules = { ...this.validationRules, ...(extendWith.validationRules || {}) }
this.validationMessages = { ...this.validationMessages, ...(extendWith.validationMessages || {}) }
return this
}
throw new Error(`[Formulario]: Formulario.extend(): should be passed an object (was ${typeof extendWith})`)
}
public runValidation (id: string): Promise<Record<string, Violation[]>> {
if (!this.registry.has(id)) {
if (!this._registry.has(id)) {
throw new Error(`[Formulario]: Formulario.runValidation(): no forms with id "${id}"`)
}
const form = this.registry.get(id) as FormularioForm
const form = this._registry.get(id) as InstanceType<FormularioFormConstructor>
return form.runValidation()
}
public resetValidation (id: string): void {
if (!this.registry.has(id)) {
if (!this._registry.has(id)) {
return
}
const form = this.registry.get(id) as FormularioForm
const form = this._registry.get(id) as InstanceType<FormularioFormConstructor>
form.resetValidation()
}
@ -71,12 +64,12 @@ export default class Formulario {
* Used by forms instances to add themselves into a registry
* @internal
*/
public register (id: string, form: FormularioForm): void {
if (this.registry.has(id)) {
public register (id: string, form: InstanceType<FormularioFormConstructor>): void {
if (this._registry.has(id)) {
throw new Error(`[Formulario]: Formulario.register(): id "${id}" is already in use`)
}
this.registry.set(id, form)
this._registry.set(id, form)
}
/**
@ -84,8 +77,8 @@ export default class Formulario {
* @internal
*/
public unregister (id: string): void {
if (this.registry.has(id)) {
this.registry.delete(id)
if (this._registry.has(id)) {
this._registry.delete(id)
}
}
@ -94,7 +87,7 @@ export default class Formulario {
* @internal
*/
public getRules (extendWith: Record<string, ValidationRuleFn> = {}): Record<string, ValidationRuleFn> {
return merge(this.validationRules, extendWith)
return { ...this.validationRules, ...extendWith }
}
/**
@ -102,12 +95,14 @@ export default class Formulario {
* @internal
*/
public getMessages (vm: Vue, extendWith: Record<string, ValidationMessageI18NFn|string>): Record<string, ValidationMessageFn> {
const raw = merge(this.validationMessages || {}, extendWith)
const raw = { ...this.validationMessages, ...extendWith }
const messages: Record<string, ValidationMessageFn> = {}
for (const name in raw) {
messages[name] = (context: ValidationContext, ...args: any[]): string => {
return typeof raw[name] === 'string' ? raw[name] : raw[name](vm, context, ...args)
messages[name] = (context: ValidationContext, ...args: unknown[]): string => {
const fn = raw[name]
return typeof fn === 'string' ? fn : fn(vm, context, ...args)
}
}

View file

@ -8,6 +8,21 @@
</template>
<script lang="ts">
import type {
Context,
Empty,
ModelGetConverter,
ModelSetConverter,
ValidationBehaviour,
UnregisterBehaviour,
} from '../types/field'
import type {
ValidationRuleFn,
ValidationMessageI18NFn,
Violation,
} from '../types/validation'
import Vue from 'vue'
import {
Component,
@ -16,41 +31,22 @@ import {
Prop,
Watch,
} from 'vue-property-decorator'
import { processConstraints, validate } from '@/validation/validator'
import { deepEquals, has, snakeToCamel } from './utils'
import {
processConstraints,
validate,
ValidationRuleFn,
ValidationMessageI18NFn,
Violation,
} from '@/validation/validator'
import {
FormularioFieldContext,
FormularioFieldModelGetConverter as ModelGetConverter,
FormularioFieldModelSetConverter as ModelSetConverter,
Empty,
} from '@/types'
import { UNREGISTER_BEHAVIOR } from '@/enum'
const VALIDATION_BEHAVIOR = {
DEMAND: 'demand',
LIVE: 'live',
SUBMIT: 'submit',
}
@Component({ name: 'FormularioField', inheritAttrs: false })
export default class FormularioField extends Vue {
@Inject({ default: '' }) __Formulario_path!: string
@Inject({ default: undefined }) __FormularioForm_set!: Function|undefined
@Inject({ default: () => (): void => {} }) __FormularioForm_emitInput!: Function
@Inject({ default: () => (): void => {} }) __FormularioForm_emitValidation!: Function
@Inject({ default: undefined }) __FormularioForm_register!: Function|undefined
@Inject({ default: undefined }) __FormularioForm_unregister!: Function|undefined
@Inject({ default: undefined }) __FormularioForm_set!: ((path: string, value: unknown) => void)|undefined
@Inject({ default: () => (): void => {} }) __FormularioForm_emitInput!: () => void
@Inject({ default: () => (): void => {} }) __FormularioForm_emitValidation!: (path: string, violations: Violation[]) => void
@Inject({ default: undefined }) __FormularioForm_register!: ((path: string, field: FormularioField) => void)|undefined
@Inject({ default: undefined }) __FormularioForm_unregister!: ((path: string, behavior: UnregisterBehaviour) => void)|undefined
@Inject({ default: () => (): Record<string, unknown> => ({}) })
__FormularioForm_getState!: () => Record<string, unknown>
__FormularioForm_getState!: () => Record<string, unknown>
@Model('input', { default: '' }) value!: unknown
@ -63,9 +59,9 @@ export default class FormularioField extends Vue {
@Prop({ default: () => ({}) }) validationRules!: Record<string, ValidationRuleFn>
@Prop({ default: () => ({}) }) validationMessages!: Record<string, ValidationMessageI18NFn|string>
@Prop({
default: VALIDATION_BEHAVIOR.DEMAND,
validator: behavior => Object.values(VALIDATION_BEHAVIOR).includes(behavior)
}) validationBehavior!: string
default: 'demand',
validator: (behavior: string) => ['demand', 'live', 'submit'].includes(behavior)
}) validationBehavior!: ValidationBehaviour
// Affects only setting of local errors
@Prop({ default: false }) errorsDisabled!: boolean
@ -74,7 +70,7 @@ export default class FormularioField extends Vue {
@Prop({ default: () => <T, U>(value: U|T): U|T => value }) modelSetConverter!: ModelSetConverter
@Prop({ default: 'div' }) tag!: string
@Prop({ default: UNREGISTER_BEHAVIOR.NONE }) unregisterBehavior!: string
@Prop({ default: 'none' }) unregisterBehavior!: UnregisterBehaviour
public proxy: unknown = this.hasModel ? this.value : ''
@ -88,14 +84,12 @@ export default class FormularioField extends Vue {
return this.__Formulario_path !== '' ? `${this.__Formulario_path}.${this.name}` : this.name
}
/**
* Determines if this formulario element is v-modeled or not.
*/
/** Determines if this formulario element is v-modeled or not. */
public get hasModel (): boolean {
return has(this.$options.propsData || {}, 'value')
}
private get context (): FormularioFieldContext<unknown> {
private get context (): Context<unknown> {
return Object.defineProperty({
name: this.fullPath,
path: this.fullPath,
@ -103,15 +97,15 @@ export default class FormularioField extends Vue {
violations: this.violations,
errors: this.localErrors,
allErrors: [...this.localErrors, ...this.violations.map(v => v.message)],
}, 'model', {
} as Context<unknown>, 'model', {
get: () => this.modelGetConverter(this.proxy),
set: (value: unknown): void => {
this.syncProxy(this.modelSetConverter(value, this.proxy))
this._syncProxy(this.modelSetConverter(value, this.proxy))
},
})
}
private get normalizedValidationRules (): Record<string, ValidationRuleFn> {
private get _normalizedValidationRules (): Record<string, ValidationRuleFn> {
const rules: Record<string, ValidationRuleFn> = {}
Object.keys(this.validationRules).forEach(key => {
rules[snakeToCamel(key)] = this.validationRules[key]
@ -119,7 +113,7 @@ export default class FormularioField extends Vue {
return rules
}
private get normalizedValidationMessages (): Record<string, ValidationMessageI18NFn|string> {
private get _normalizedValidationMessages (): Record<string, ValidationMessageI18NFn|string> {
const messages: Record<string, ValidationMessageI18NFn|string> = {}
Object.keys(this.validationMessages).forEach(key => {
messages[snakeToCamel(key)] = this.validationMessages[key]
@ -128,42 +122,70 @@ export default class FormularioField extends Vue {
}
@Watch('value')
private onValueChange (): void {
this.syncProxy(this.value)
private _onValueChange (): void {
this._syncProxy(this.value)
}
@Watch('proxy')
private onProxyChange (): void {
if (this.validationBehavior === VALIDATION_BEHAVIOR.LIVE) {
private _onProxyChange (): void {
if (this.validationBehavior === 'live') {
this.runValidation()
} else {
this.resetValidation()
}
}
/**
* @internal
*/
/** @internal */
public created (): void {
if (typeof this.__FormularioForm_register === 'function') {
this.__FormularioForm_register(this.fullPath, this)
}
if (this.validationBehavior === VALIDATION_BEHAVIOR.LIVE) {
if (this.validationBehavior === 'live') {
this.runValidation()
}
}
/**
* @internal
*/
/** @internal */
public beforeDestroy (): void {
if (typeof this.__FormularioForm_unregister === 'function') {
this.__FormularioForm_unregister(this.fullPath, this.unregisterBehavior)
}
}
private syncProxy (value: unknown): void {
public runValidation (): Promise<Violation[]> {
this.validationRun = this._validate().then(violations => {
this.violations = violations
this._emitValidation(this.fullPath, violations)
return this.violations
})
return this.validationRun
}
public hasValidationErrors (): Promise<boolean> {
return new Promise(resolve => {
this.$nextTick(() => {
this.validationRun.then(() => resolve(this.violations.length > 0))
})
})
}
/** @internal */
public setErrors (errors: string[]): void {
if (!this.errorsDisabled) {
this.localErrors = errors
}
}
/** @internal */
public resetValidation (): void {
this.localErrors = []
this.violations = []
}
private _syncProxy (value: unknown): void {
if (!deepEquals(value, this.proxy)) {
this.proxy = value
this.$emit('input', value)
@ -175,22 +197,11 @@ export default class FormularioField extends Vue {
}
}
public runValidation (): Promise<Violation[]> {
this.validationRun = this.validate().then(violations => {
this.violations = violations
this.emitValidation(this.fullPath, violations)
return this.violations
})
return this.validationRun
}
private validate (): Promise<Violation[]> {
private _validate (): Promise<Violation[]> {
return validate(processConstraints(
this.validation,
this.$formulario.getRules(this.normalizedValidationRules),
this.$formulario.getMessages(this, this.normalizedValidationMessages),
this.$formulario.getRules(this._normalizedValidationRules),
this.$formulario.getMessages(this, this._normalizedValidationMessages),
), {
value: this.proxy,
name: this.fullPath,
@ -198,36 +209,11 @@ export default class FormularioField extends Vue {
})
}
private emitValidation (path: string, violations: Violation[]): void {
private _emitValidation (path: string, violations: Violation[]): void {
this.$emit('validation', { path, violations })
if (typeof this.__FormularioForm_emitValidation === 'function') {
this.__FormularioForm_emitValidation(path, violations)
}
}
public hasValidationErrors (): Promise<boolean> {
return new Promise(resolve => {
this.$nextTick(() => {
this.validationRun.then(() => resolve(this.violations.length > 0))
})
})
}
/**
* @internal
*/
public setErrors (errors: string[]): void {
if (!this.errorsDisabled) {
this.localErrors = errors
}
}
/**
* @internal
*/
public resetValidation (): void {
this.localErrors = []
this.violations = []
}
}
</script>

View file

@ -5,7 +5,11 @@
</template>
<script lang="ts">
import type { UnregisterBehaviour } from '../types/field'
import type { Violation } from '../types/validation'
import Vue from 'vue'
import {
Component,
Model,
@ -13,21 +17,18 @@ import {
Provide,
Watch,
} from 'vue-property-decorator'
import {
id,
clone,
deepEquals,
get,
has,
merge,
set,
unset,
} from '@/utils'
import { FormularioField } from '@/types'
import { Violation } from '@/validation/validator'
import { UNREGISTER_BEHAVIOR } from '@/enum'
const update = (state: Record<string, unknown>, path: string, value: unknown): Record<string, unknown> => {
if (value === undefined) {
@ -57,7 +58,7 @@ export default class FormularioForm extends Vue {
private localFormErrors: string[] = []
private get fieldsErrorsComputed (): Record<string, string[]> {
return merge(this.fieldsErrors || {}, this.localFieldsErrors)
return { ...this.fieldsErrors, ...this.localFieldsErrors }
}
private get formErrorsComputed (): string[] {
@ -90,11 +91,11 @@ export default class FormularioForm extends Vue {
}
@Provide('__FormularioForm_unregister')
private unregister (path: string, behavior: string): void {
private unregister (path: string, behavior: UnregisterBehaviour): void {
if (this.registry.has(path)) {
this.registry.delete(path)
if (behavior === UNREGISTER_BEHAVIOR.UNSET) {
if (behavior === 'unset') {
this.proxy = unset(this.proxy, path) as Record<string, unknown>
this.emitInput()
}
@ -183,17 +184,17 @@ export default class FormularioForm extends Vue {
})
}
public setErrors ({ fieldsErrors, formErrors }: {
fieldsErrors?: Record<string, string[]>;
public setErrors ({ formErrors, fieldsErrors }: {
formErrors?: string[];
fieldsErrors?: Record<string, string[]>;
}): void {
this.localFieldsErrors = fieldsErrors || {}
this.localFormErrors = formErrors || []
this.localFieldsErrors = fieldsErrors || {}
}
public resetValidation (): void {
this.localFieldsErrors = {}
this.localFormErrors = []
this.localFieldsErrors = {}
this.registry.forEach((field: FormularioField) => {
field.resetValidation()
})

View file

@ -1,4 +0,0 @@
export const UNREGISTER_BEHAVIOR = {
NONE: 'none',
UNSET: 'unset',
}

View file

@ -1,23 +1,26 @@
import { VueConstructor } from 'vue'
import type { VueConstructor } from 'vue'
import type { Options } from '../types/plugin'
import Formulario, { FormularioOptions } from '@/Formulario.ts'
import Formulario from '@/Formulario'
import FormularioField from '@/FormularioField.vue'
import FormularioFieldGroup from '@/FormularioFieldGroup.vue'
import FormularioForm from '@/FormularioForm.vue'
export {
Formulario,
FormularioField,
FormularioFieldGroup,
FormularioForm,
}
export default {
Formulario,
install (Vue: VueConstructor, options?: FormularioOptions): void {
install (Vue: VueConstructor, options?: Options): void {
Vue.component('FormularioField', FormularioField)
Vue.component('FormularioFieldGroup', FormularioFieldGroup)
Vue.component('FormularioForm', FormularioForm)
// @deprecated Use FormularioField instead
Vue.component('FormularioInput', FormularioField)
// @deprecated Use FormularioFieldGroup instead
Vue.component('FormularioGrouping', FormularioFieldGroup)
Vue.mixin({
beforeCreate () {
const o = this.$options as Record<string, any>

9
src/shims-ext.d.ts vendored
View file

@ -3,12 +3,7 @@ import Formulario from '@/Formulario'
declare module 'vue/types/vue' {
interface Vue {
$formulario: Formulario;
$route: VueRoute;
$t: Function;
$tc: Function;
}
interface VueRoute {
path: string;
$t: any;
$tc: any;
}
}

View file

@ -1,10 +1,6 @@
import Vue from 'vue'
import { Violation } from '@/validation/validator'
import type { Violation } from '../types/validation'
export interface FormularioForm extends Vue {
runValidation(): Promise<Record<string, Violation[]>>;
resetValidation(): void;
}
import Vue from 'vue'
export interface FormularioField extends Vue {
hasModel: boolean;
@ -14,25 +10,6 @@ export interface FormularioField extends Vue {
resetValidation(): void;
}
export type FormularioFieldContext<T> = {
model: T;
name: string;
runValidation(): Promise<Violation[]>;
violations: Violation[];
errors: string[];
allErrors: string[];
}
export interface FormularioFieldModelGetConverter {
<U, T>(value: U|Empty): U|T|Empty;
}
export interface FormularioFieldModelSetConverter {
<T, U>(curr: U|T, prev: U|Empty): U|T;
}
export type Empty = undefined | null
export enum TYPE {
ARRAY = 'ARRAY',
BIGINT = 'BIGINT',
@ -95,7 +72,7 @@ export function typeOf (value: unknown): string {
return 'InstanceOf<' + (constructorOf(value) as { name?: string }).name + '>'
}
throw new Error()
throw new Error('[Formulario] typeOf - unknown type detected')
}
export function isScalar (value: unknown): boolean {

View file

@ -9,7 +9,8 @@ const cloneInstance = <T>(original: T): T => {
* case of needing to unbind reactive watchers.
*/
export default function clone<T = unknown> (value: T): T {
if (isScalar(value)) {
// scalars & immutables
if (isScalar(value) || value instanceof Blob) {
return value
}

View file

@ -1,7 +1,6 @@
export { default as id } from './id'
export { default as clone } from './clone'
export { default as has } from './has'
export { default as merge } from './merge'
export { get, set, unset } from './access'
export { default as regexForFormat } from './regexForFormat'
export { deepEquals, shallowEquals } from './compare'

View file

@ -1,40 +0,0 @@
import isPlainObject from 'is-plain-object'
import has from '@/utils/has.ts'
/**
* Create a new object by copying properties of base and mergeWith.
* Note: arrays don't overwrite - they push
*
* @param {Object} a
* @param {Object} b
* @param {boolean} concatArrays
*/
export default function merge (
a: Record<string, any>,
b: Record<string, any>,
concatArrays = true
): Record<string, any> {
const merged: Record<string, any> = {}
for (const key in a) {
if (has(b, key)) {
if (isPlainObject(b[key]) && isPlainObject(a[key])) {
merged[key] = merge(a[key], b[key], concatArrays)
} else if (concatArrays && Array.isArray(a[key]) && Array.isArray(b[key])) {
merged[key] = a[key].concat(b[key])
} else {
merged[key] = b[key]
}
} else {
merged[key] = a[key]
}
}
for (const prop in b) {
if (!has(merged, prop)) {
merged[prop] = b[prop]
}
}
return merged
}

View file

@ -1,7 +1,7 @@
import {
import type {
ValidationContext,
ValidationMessageI18NFn,
} from '@/validation/validator'
} from '../../types/validation'
/**
* Message builders, names match rules names, see @/validation/rules

View file

@ -1,9 +1,10 @@
import isUrl from 'is-url'
import { has, regexForFormat, shallowEquals } from '@/utils'
import {
import type {
ValidationContext,
ValidationRuleFn,
} from '@/validation/validator'
} from '../../types/validation'
import isUrl from 'is-url'
import { has, regexForFormat, shallowEquals } from '@/utils'
const rules: Record<string, ValidationRuleFn> = {
/**
@ -165,7 +166,7 @@ const rules: Record<string, ValidationRuleFn> = {
}
if (typeof value === 'string' || (force === 'length')) {
value = !isNaN(value) ? value.toString() : value
value = !isNaN(value) ? String(value) : value
return value.length <= maximum
}
@ -187,7 +188,7 @@ const rules: Record<string, ValidationRuleFn> = {
}
if (typeof value === 'string' || (force === 'length')) {
value = !isNaN(value) ? value.toString() : value
value = !isNaN(value) ? String(value) : value
return value.length >= minimum
}

View file

@ -1,42 +1,14 @@
import type {
ValidationContext,
ValidationMessageFn,
ValidationRuleFn,
Validator,
ValidatorGroup,
Violation,
} from '../../types/validation'
import { has, snakeToCamel } from '@/utils'
export interface Validator {
(context: ValidationContext): Promise<Violation|null>;
}
export interface Violation {
message: string;
rule: string|null;
args: any[];
context: ValidationContext|null;
}
export interface ValidationRuleFn {
(context: ValidationContext, ...args: any[]): Promise<boolean>|boolean;
}
export interface ValidationMessageFn {
(context: ValidationContext, ...args: any[]): string;
}
export interface ValidationMessageI18NFn {
(vm: Vue, context: ValidationContext, ...args: any[]): string;
}
export interface ValidationContext {
// The value of the field (do not mutate!),
value: any;
// If wrapped in a FormulateForm, the value of other form fields.
formValues: Record<string, any>;
// The validation name to be used
name: string;
}
export type ValidatorGroup = {
validators: Validator[];
bail: boolean;
}
export function createValidator (
ruleFn: ValidationRuleFn,
ruleName: string|null,

View file

@ -4,7 +4,6 @@ import { mount } from '@vue/test-utils'
import flushPromises from 'flush-promises'
import Formulario from '@/index.ts'
import FormularioFieldGroup from '@/FormularioFieldGroup.vue'
import FormularioForm from '@/FormularioForm.vue'
Vue.use(Formulario)

View file

@ -76,4 +76,11 @@ describe('clone', () => {
expect(copy.sample.doSomething).toBeTruthy()
expect(copy.sample.doSomething).not.toThrow()
})
test('does not create a copy of a blob', () => {
const blob = new Blob(['{"fieldA": "fieldA"}'], { type : 'application/json' })
const copy = clone(blob)
expect(blob === copy).toBeTruthy()
})
})

View file

@ -1,56 +0,0 @@
import merge from '@/utils/merge.ts'
describe('merge', () => {
it('Can merge simple object', () => {
expect(merge({
optionA: true,
optionB: '1234',
}, {
optionA: false,
})).toEqual({
optionA: false,
optionB: '1234',
})
})
it('Can add to simple array', () => {
expect(merge({
optionA: true,
optionB: ['first', 'second']
}, {
optionB: ['third']
}, true)).toEqual({
optionA: true,
optionB: ['first', 'second', 'third']
})
})
it('Can merge recursively', () => {
expect(merge({
optionA: true,
optionC: {
first: '123',
third: {
a: 'b',
},
},
optionB: '1234',
}, {
optionB: '567',
optionC: {
first: '1234',
second: '789',
}
})).toEqual({
optionA: true,
optionC: {
first: '1234',
third: {
a: 'b',
},
second: '789',
},
optionB: '567',
})
})
})

34
types/field.d.ts vendored Normal file
View file

@ -0,0 +1,34 @@
import type { Violation } from './validation'
export type Empty = undefined | null
export type Context<T> = {
model: T;
name: string;
path: string;
violations: Violation[];
errors: string[];
allErrors: string[];
runValidation(): Promise<Violation[]>;
}
export interface ModelGetConverter {
<U, T>(value: U|Empty): U|T|Empty;
}
export interface ModelSetConverter {
<T, U>(curr: U|T, prev: U|Empty): U|T;
}
/**
* - 'demand': triggers validation on manual call
* - 'live': triggers validation on any changes
* - 'submit': triggers validation on form submit event
*/
export type ValidationBehaviour = 'demand' | 'live' | 'submit'
/**
* - 'none': no any specific effects
* - 'unset': the value under field's path will be unset and path will be removed from the state
*/
export type UnregisterBehaviour = 'none' | 'unset'

17
types/form.d.ts vendored Normal file
View file

@ -0,0 +1,17 @@
import type { DefineComponent } from './vue'
import type { Violation } from './validation'
export type FormularioFormConstructor = DefineComponent<{
id?: string;
state?: Record<string, unknown>;
fieldsErrors?: Record<string, string[]>;
formErrors?: string[];
}, {
setErrors ({ formErrors, fieldsErrors }: {
formErrors?: string[];
fieldsErrors?: Record<string, string[]>;
}): void;
runValidation(): Promise<Record<string, Violation[]>>;
hasValidationErrors (): Promise<boolean>;
resetValidation(): void;
}>

9
types/plugin.d.ts vendored Normal file
View file

@ -0,0 +1,9 @@
import type {
ValidationMessageI18NFn,
ValidationRuleFn
} from './validation'
export interface Options {
validationRules?: Record<string, ValidationRuleFn>;
validationMessages?: Record<string, ValidationMessageI18NFn|string>;
}

38
types/validation.d.ts vendored Normal file
View file

@ -0,0 +1,38 @@
import { Vue } from 'vue/types/vue'
export interface ValidationContext {
// The value of the field (do not mutate!),
value: any;
// If wrapped in a FormulateForm, the value of other form fields.
formValues: Record<string, any>;
// The validation name to be used
name: string;
}
export interface Violation {
message: string;
rule: string|null;
args: any[];
context: ValidationContext|null;
}
export interface Validator {
(context: ValidationContext): Promise<Violation|null>;
}
export type ValidatorGroup = {
validators: Validator[];
bail: boolean;
}
export interface ValidationRuleFn {
(context: ValidationContext, ...args: any[]): Promise<boolean>|boolean;
}
export interface ValidationMessageFn {
(context: ValidationContext, ...args: any[]): string;
}
export interface ValidationMessageI18NFn {
(vm: Vue, context: ValidationContext, ...args: any[]): string;
}

3
types/vue.d.ts vendored Normal file
View file

@ -0,0 +1,3 @@
import type { Vue, VueConstructor } from 'vue/types/vue'
export type DefineComponent<Props, Methods> = VueConstructor<Vue & Required<Props> & Methods>

207
web-types.json Normal file
View file

@ -0,0 +1,207 @@
{
"$schema": "https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json",
"framework": "vue",
"name": "@omnica/accordion-vue2",
"version": "0.24.22",
"js-types-syntax": "typescript",
"description-markup": "markdown",
"contributions": {
"html": {
"vue-components": [
{
"name": "FormularioForm",
"description": "Form root",
"source": {
"module": "@retailcrm/vue-formulario",
"symbol": "FormularioForm"
},
"props": [
{
"name": "state",
"type": "object",
"default": "{}",
"description": ""
},
{
"name": "id",
"type": "string",
"default": "id('formulario-form')",
"description": ""
},
{
"name": "fieldsErrors",
"type": "object",
"default": "{}",
"description": "Describes validation errors of concrete fields"
},
{
"name": "formErrors",
"type": "array",
"default": "[]",
"description": "Describes validation errors of entire state"
}
],
"events": [
{
"name": "input",
"description": "Occurs on state change",
"arguments": [
{
"name": "...",
"type": {
"name": "any"
}
}
]
},
{
"name": "validation",
"description": "Occurs at the end of a validation run",
"arguments": [
{
"name": "...",
"type": {
"name": "any"
}
}
]
}
],
"slots": [
{
"name": "default",
"description": "Form content",
"scoped": true
}
]
},
{
"name": "FormularioField",
"description": "Form field",
"source": {
"module": "@retailcrm/vue-formulario",
"symbol": "FormularioField"
},
"props": [
{
"name": "value",
"type": "any",
"description": "The field's value, if not set explicitly, will be extracted from the state using 'path'"
},
{
"name": "name",
"type": "string",
"description": "Path to field's value in the state",
"required": true
},
{
"name": "validation",
"type": "string|array",
"description": ""
},
{
"name": "validationRules",
"type": "object",
"description": "Validation rules override/extension opportunity",
"default": "{}"
},
{
"name": "validationMessages",
"type": "object",
"description": "Validation messages override/extension opportunity",
"default": "{}"
},
{
"name": "validationBehavior",
"type": "string",
"description": "",
"default": "'demand'"
},
{
"name": "errorsDisabled",
"type": "boolean",
"description": "Disables passing errors to the field from FormularioForm's fieldsErrors",
"default": "false"
},
{
"name": "modelGetConverter",
"type": "function",
"description": "Simple middleware that provides opportunity to transform value before passing it to a template"
},
{
"name": "modelSetConverter",
"type": "function",
"description": "Simple middleware that provides opportunity to transform new value before assigning"
},
{
"name": "tag",
"type": "string",
"description": "Root element's tagName in lowercase"
},
{
"name": "unregisterBehavior",
"type": "string",
"description": "Possible values: 'none', 'unset'",
"default": "'none'"
}
],
"events": [
{
"name": "input",
"description": "Occurs on value change",
"arguments": [
{
"name": "...",
"type": {
"name": "any"
}
}
]
},
{
"name": "validation",
"description": "Occurs at the end of a validation run",
"arguments": [
{
"name": "...",
"type": {
"name": "any"
}
}
]
}
],
"slots": [
{
"name": "default",
"description": "Field content",
"scoped": true
}
]
},
{
"name": "FormularioFieldGroup",
"description": "Field group",
"source": {
"module": "@retailcrm/vue-formulario",
"symbol": "FormularioFieldGroup"
},
"props": [
{
"name": "name",
"type": "string",
"description": "Path to a nested state",
"required": true
}
],
"slots": [
{
"name": "default",
"description": "Group content"
}
]
}
]
}
}
}

2878
yarn.lock

File diff suppressed because it is too large Load diff