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

Compare commits

...

35 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
1on
3eeff5fe1e chore(release): 0.7.0 2021-09-30 13:17:11 +03:00
Kruglov Kirill
e3084fdf85
Merge pull request #35 from cmath10/field-unregister-behavior
feat!: Added property "unregisterBehavior" to FormularioField to cont…
2021-09-30 13:15:29 +03:00
Zaytsev Kirill
d39ca17e45 feat!: Added property "unregisterBehavior" to FormularioField to control value unset behavior on field component removal
Defaults to "none" which means value will not be unset and path will not be remove
2021-09-30 12:33:54 +03:00
34 changed files with 2729 additions and 4332 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,73 @@
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)
### ⚠ BREAKING CHANGES
* Added property "unregisterBehavior" to FormularioField to control value unset behavior on field component removal
### Features
* Added property "unregisterBehavior" to FormularioField to control value unset behavior on field component removal ([d39ca17](https://github.com/retailcrm/vue-formulario/commit/d39ca17e45cb5957bd9b9916b6e904993e660bc5))
### [0.6.3](https://github.com/retailcrm/vue-formulario/compare/v0.6.2...v0.6.3) (2021-09-29)

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.6.3",
"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,39 +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'
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
@ -61,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
@ -72,6 +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: 'none' }) unregisterBehavior!: UnregisterBehaviour
public proxy: unknown = this.hasModel ? this.value : ''
@ -85,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,
@ -100,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]
@ -116,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]
@ -125,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.__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)
@ -172,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,
@ -195,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,19 +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'
const update = (state: Record<string, unknown>, path: string, value: unknown): Record<string, unknown> => {
if (value === undefined) {
@ -55,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[] {
@ -88,11 +91,14 @@ export default class FormularioForm extends Vue {
}
@Provide('__FormularioForm_unregister')
private unregister (path: string): void {
private unregister (path: string, behavior: UnregisterBehaviour): void {
if (this.registry.has(path)) {
this.registry.delete(path)
this.proxy = unset(this.proxy, path) as Record<string, unknown>
this.emitInput()
if (behavior === 'unset') {
this.proxy = unset(this.proxy, path) as Record<string, unknown>
this.emitInput()
}
}
}
@ -178,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,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

@ -286,4 +286,37 @@ describe('FormularioField', () => {
[{ date: new Date('2001-05-12') }],
])
})
test('unregister behavior', async () => {
const wrapper = mount({
props: {
formExists: {
type: Boolean,
default: true,
}
},
data: () => ({ state: { fieldA: '', fieldB: '' } }),
watch: {
state () {
this.$emit('updated', this.state)
},
},
template: `
<div>
<FormularioForm v-if="formExists" v-model="state">
<FormularioField name="fieldA" />
<FormularioField name="fieldB" unregister-behavior="unset" />
</FormularioForm>
</div>
`,
})
await wrapper.vm.$nextTick()
wrapper.setProps({ formExists: false })
await wrapper.vm.$nextTick()
expect(wrapper.emitted('updated')).toEqual([[{ fieldA: '' }]])
})
})

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