diff --git a/packages/vue-vuetify/README.md b/packages/vue-vuetify/README.md index e782a711d7..3dd4e0d24c 100644 --- a/packages/vue-vuetify/README.md +++ b/packages/vue-vuetify/README.md @@ -14,7 +14,7 @@ The renderers are in a preview state. Install JSON Forms Core, Vue 3 and Vue 3 Vuetify Renderers. ```bash -npm i --save @jsonforms/core @jsonforms/vue @jsonforms/vue-vuetify +npm i --save @jsonforms/core @jsonforms/vue @jsonforms/vue-vuetify splitpanes ``` Also add the packages to the transpile dependencies in the `vite.config.js` file: @@ -128,6 +128,44 @@ For more information on how JSON Forms can be configured, please see the [README ## Customization +### Empty property names + +`allowEmptyPropertyNames` controls whether Additional Properties can add or rename +properties to empty or whitespace-only names, and whether the Mixed renderer can +rename tree properties to those names. It defaults to `false`: names for which +`name.trim().length === 0` are rejected. + +Enable it globally through the JSON Forms `config` prop: + +```js +const config = { allowEmptyPropertyNames: true }; +``` + +Or set it for an object control through `uischema.options`: + +```json +{ + "type": "Control", + "scope": "#/properties/settings", + "options": { + "allowEmptyPropertyNames": true + } +} +``` + +The UI-schema option takes precedence over global config, including an explicit +`false` overriding global `true`. + +Accepted names are preserved exactly; trimming is only used to check whether a +name is blank. Schema constraints such as `propertyNames.minLength` and duplicate +name checks still apply when the option is enabled. Having a `propertyNames` +schema does not automatically enable empty names. + +Existing empty or whitespace-only keys remain visible and editable, and can be +deleted or renamed to a permitted name, subject to the usual permissions and +schema restrictions. This option controls property **names**, not how empty +property **values** are stored or cleared. + ### Prepend and Append Slots All control renderers now support `prepend` and `append` slots, allowing you to add custom content before or after input fields without creating entirely custom renderers. diff --git a/packages/vue-vuetify/dev/components/ExampleSettings.vue b/packages/vue-vuetify/dev/components/ExampleSettings.vue index 2c8df6fe2d..7e829997b0 100644 --- a/packages/vue-vuetify/dev/components/ExampleSettings.vue +++ b/packages/vue-vuetify/dev/components/ExampleSettings.vue @@ -464,6 +464,22 @@ const layouts = appstoreLayouts.map((value: AppstoreLayouts) => ({ + + + + + Allow adding or renaming properties to empty or whitespace-only + names. Schema constraints still apply; UI-schema options override + this setting. + + + diff --git a/packages/vue-vuetify/dev/store/index.ts b/packages/vue-vuetify/dev/store/index.ts index 1e8d436d23..4355b69e08 100644 --- a/packages/vue-vuetify/dev/store/index.ts +++ b/packages/vue-vuetify/dev/store/index.ts @@ -35,6 +35,7 @@ const appstore = reactive({ enableFilterErrorsBeforeTouch: false, filterErrorKeywordsBeforeTouch: ['required'], allowAdditionalPropertiesIfMissing: false, + allowEmptyPropertyNames: false, }, locale: useLocalStorage('vuetify-example-locale', 'en'), }, diff --git a/packages/vue-vuetify/dev/views/ExampleView.vue b/packages/vue-vuetify/dev/views/ExampleView.vue index 653993197b..17269eadca 100644 --- a/packages/vue-vuetify/dev/views/ExampleView.vue +++ b/packages/vue-vuetify/dev/views/ExampleView.vue @@ -29,8 +29,7 @@ import examples from '../examples'; import { useAppStore } from '../store'; import { createAjv } from '../validate'; -import { Pane, Splitpanes } from 'splitpanes'; -import 'splitpanes/dist/splitpanes.css'; +import { VPane, VSplitpanes } from '../../src/components'; import { getCustomRenderersForExample } from '../renderers'; const { extendedVuetifyRenderers } = await import('../../src'); @@ -332,12 +331,11 @@ const handleAction = (action: Action) => {
- - + @@ -348,8 +346,8 @@ const handleAction = (action: Action) => { - - + + @@ -389,8 +387,8 @@ const handleAction = (action: Action) => { :editorBeforeMount="registerValidations" > - - + +
@@ -509,28 +507,3 @@ const handleAction = (action: Action) => { - diff --git a/packages/vue-vuetify/package.json b/packages/vue-vuetify/package.json index 083304fac3..472c0167bd 100644 --- a/packages/vue-vuetify/package.json +++ b/packages/vue-vuetify/package.json @@ -59,7 +59,7 @@ "doc": "typedoc --tsconfig tsconfig.typedoc.json --name 'JSON Forms Vue Vuetify Renderers' --out docs --entryPoints 'src/**/*.ts' 'lib/index.d.ts'", "test": "vitest --watch=false", "build-only": "cross-env NODE_OPTIONS=\"--max-old-space-size=4096\" vite build", - "type-check": "vue-tsc -p tsconfig.lib.json" + "type-check": "vue-tsc -p tsconfig.lib.json && vue-tsc --noEmit -p tsconfig.vitest.json" }, "peerDependencies": { "@jsonforms/core": "3.9.0-alpha.1", @@ -68,6 +68,7 @@ "dayjs": "^1.10.6", "lodash": "^4.17.21", "maska": "^2.1.11", + "splitpanes": "^3.1.5", "vue": "^3.5.0", "vuetify": "^3.11.0" }, diff --git a/packages/vue-vuetify/src/complex/MixedRenderer.vue b/packages/vue-vuetify/src/complex/MixedRenderer.vue index 5f572a7f17..f81347df80 100644 --- a/packages/vue-vuetify/src/complex/MixedRenderer.vue +++ b/packages/vue-vuetify/src/complex/MixedRenderer.vue @@ -1,13 +1,13 @@