Skip to content

Backoffice: Preserve user-supplied property editor UI group names (closes #22189) - #22196

Merged
nielslyngsoe merged 5 commits into
v17/devfrom
v17/bugfix/22189-use-provided-property-editor-ui-group-names
May 13, 2026
Merged

Backoffice: Preserve user-supplied property editor UI group names (closes #22189)#22196
nielslyngsoe merged 5 commits into
v17/devfrom
v17/bugfix/22189-use-provided-property-editor-ui-group-names

Conversation

@AndyButland

@AndyButland AndyButland commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Description

#22189 reports a problem with certain group names provided as meta data for property editor UIs, where the resulting text is transformed into something the package or project developer doesn't want.

E.g. illustratively "My CusTom UI Group" would become "My Cus Tom U I Group" (or, more realistically "SEO" would become "S E O").

To fix I've added correct display values to all group names for core property editors - so "richContent" is now "Rich Content".

We have to consider external packages may still register property editor UIs with camelCase group names (e.g. 'richContent', 'pickers'). So to that end I've introduced a fromCamelCaseIfCamelCase function, and called this instead of fromCamelCase as we had before. This is a wrapper around fromCamelCase that only transforms strings that actually look like camelCase (start with a lowercase letter and contain no spaces).

Display-ready names are returned as-is. Existing external packages using the old camelCase names will continue to display correctly without any changes on their part.

Testing

  • New unit tests for fromCamelCaseIfCamelCase (camelCase, single word, spaces, PascalCase, uppercase-start) are added.
  • Run site, create a data type, open property editor picker — verify built-in groups display correctly.
  • Verify the provided bug reproduction group shows MyCusTomUIGroup as is.

Reproduction sample

Place these two files in App_Plugins.

umbraco-page.json

{
    "$schema": "../../umbraco-package-schema.json",
    "name": "BugRepro.22189",
    "version": "0.1.0",
    "extensions": [
        {
            "type": "propertyEditorUi",
            "alias": "BugRepro.PropertyEditorUi.22189",
            "name": "Bug Repro 22189",
            "element": "/App_Plugins/BugRepro22189/editor.js",
            "elementName": "bug-repro-22189-editor",
            "meta": {
                "label": "Bug Repro 22189",
                "icon": "icon-bug",
                "group": "MyCusTomUIGroup",
                "propertyEditorSchemaAlias": "Umbraco.Plain.String"
            }
        }
    ]
}

editor.js

import { UmbElementMixin } from "@umbraco-cms/backoffice/element-api";

class BugRepro22189Editor extends UmbElementMixin(HTMLElement) {
    #value = "";

    set value(val) {
        this.#value = val || "";
        this.#render();
    }

    get value() {
        return this.#value;
    }

    connectedCallback() {
        super.connectedCallback();
        this.#render();
    }

    #render() {
        this.innerHTML = `
            <p>
                This property editor exists to reproduce
                <a href="https://github.com/umbraco/Umbraco-CMS/issues/22189" target="_blank">#22189</a>.
            </p>
            <p>
                Its manifest sets <code>"group": "MyCusTomUIGroup"</code>.<br/>
                <strong>Expected:</strong> The group tab reads <em>MyCusTomUIGroup</em>.<br/>
                <strong>Actual:</strong> The group tab reads <em>My Cus Tom U I Group</em>
                (spaces inserted before every capital letter).
            </p>
            <input type="text" value="${this.#value}" />
        `;

        const input = this.querySelector("input");
        input.addEventListener("input", (e) => {
            this.#value = e.target.value;
            this.dispatchEvent(
                new CustomEvent("property-value-change", { bubbles: true, composed: true })
            );
        });
    }
}

customElements.define("bug-repro-22189-editor", BugRepro22189Editor);

This item has been added to our backlog AB#67943

Copilot AI review requested due to automatic review settings March 19, 2026 15:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates how property editor UI group names are displayed in the backoffice so that user-supplied, display-ready group names are preserved (instead of being blindly “de-camelCased”), while keeping backward compatibility for packages still using legacy camelCase group names.

Changes:

  • Added fromCamelCaseIfCamelCase() utility and accompanying unit tests.
  • Updated picker/grouping UI logic to use fromCamelCaseIfCamelCase instead of fromCamelCase when rendering/grouping property editor UI groups.
  • Updated built-in manifests to use title-cased/display-ready group names (e.g. Common, Rich Content, Pickers, etc.).

Reviewed changes

Copilot reviewed 72 out of 72 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Umbraco.Web.UI.Client/src/packages/user/user/property-editor/user-picker/manifests.ts Updates manifest group to display-ready casing (People).
src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/toolbar-configuration/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/tiptap-rte/manifests.ts Updates manifest group to Rich Content.
src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/statusbar-configuration/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/tiptap/property-editors/extensions-configuration/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/property-editors/stylesheet-picker/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/tags/property-editors/tags/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/static-file/property-editors/static-file-picker/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/value-type/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/textarea/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/text-box/manifests.ts Updates manifest groups to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/select/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/property-editors/radio-button-list/manifests.ts Updates manifest group to Lists.
src/Umbraco.Web.UI.Client/src/packages/property-editors/order-direction/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/number/manifests.ts Updates manifest groups to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/number-range/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/multiple-text-string/manifests.ts Updates manifest group to Lists.
src/Umbraco.Web.UI.Client/src/packages/property-editors/label/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/icon-picker/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/eye-dropper/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/property-editors/entity-data-picker/property-editor/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/property-editors/entity-data-picker/property-editor/config/picker-views/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/property-editors/dropdown/manifests.ts Updates manifest group to Lists.
src/Umbraco.Web.UI.Client/src/packages/property-editors/dimensions/manifest.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/time-only-picker/manifests.ts Updates manifest group to Date.
src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-with-time-zone-picker/manifests.ts Updates manifest group to Date.
src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-time-picker/manifests.ts Updates manifest group to Date.
src/Umbraco.Web.UI.Client/src/packages/property-editors/date-time/date-only-picker/manifests.ts Updates manifest group to Date.
src/Umbraco.Web.UI.Client/src/packages/property-editors/date-picker/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/property-editors/content-picker/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/property-editors/content-picker/config/source-type/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/property-editors/content-picker/config/source-content/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/property-editors/color-swatches-editor/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/property-editors/color-picker/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/manifests.ts Updates manifest group to Lists.
src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/config/order-by/manifests.ts Updates manifest group to Lists.
src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/config/layout/manifests.ts Updates manifest group to Lists.
src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/config/column/manifests.ts Updates manifest group to Lists.
src/Umbraco.Web.UI.Client/src/packages/property-editors/checkbox-list/manifests.ts Updates manifest group to Lists.
src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/manifests.ts Updates manifest group to Lists.
src/Umbraco.Web.UI.Client/src/packages/multi-url-picker/property-editor/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/members/member/property-editor/member-picker/manifests.ts Updates manifest group to People.
src/Umbraco.Web.UI.Client/src/packages/members/member-group/property-editor/member-group-picker/manifests.ts Updates manifest group to People.
src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/upload-field/manifests.ts Updates manifest group to Media.
src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-picker/manifests.ts Updates manifest group to Media.
src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/media-entity-picker/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/image-crops/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/image-cropper/manifests.ts Updates manifest group to Media.
src/Umbraco.Web.UI.Client/src/packages/media/media-types/property-editors/media-type-picker/manifests.ts Updates manifest group to Advanced.
src/Umbraco.Web.UI.Client/src/packages/markdown-editor/property-editors/markdown-editor/manifests.ts Updates manifest group to Rich Content.
src/Umbraco.Web.UI.Client/src/packages/documents/documents/property-editors/document-picker/manifests.ts Updates manifest group to Pickers.
src/Umbraco.Web.UI.Client/src/packages/documents/document-types/property-editors/document-type-picker/manifests.ts Updates manifest group to Advanced.
src/Umbraco.Web.UI.Client/src/packages/data-type/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts Uses fromCamelCaseIfCamelCase when grouping/rendering group names in the data type picker flow.
src/Umbraco.Web.UI.Client/src/packages/core/utils/string/from-camel-case/from-camel-case.function.ts Adds fromCamelCaseIfCamelCase utility to preserve display-ready group names.
src/Umbraco.Web.UI.Client/src/packages/core/utils/string/from-camel-case/from-camel-case.function.test.ts Adds unit tests for fromCamelCaseIfCamelCase.
src/Umbraco.Web.UI.Client/src/packages/core/property-editor/ui-picker-modal/property-editor-ui-picker-modal.element.ts Uses fromCamelCaseIfCamelCase when grouping property editor UIs by group.
src/Umbraco.Web.UI.Client/src/packages/core/property-editor/extensions/property-editor.extension.ts Updates docs to recommend display-ready group names and note legacy camelCase support.
src/Umbraco.Web.UI.Client/src/packages/code-editor/property-editor/manifests.ts Updates manifest group to Rich Content.
src/Umbraco.Web.UI.Client/src/packages/block/block-single/property-editors/block-single-type-configuration/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/block/block-single/property-editors/block-single-editor/manifests.ts Updates manifest group to Rich Content.
src/Umbraco.Web.UI.Client/src/packages/block/block-rte/property-editors/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/block/block-list/property-editors/block-list-type-configuration/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/block/block-list/property-editors/block-list-editor/manifests.ts Updates manifest group to Rich Content.
src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-type-configuration/manifests.ts Updates manifest group to Blocks.
src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-layout-stylesheet/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-group-configuration/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts Updates manifest group to Rich Content.
src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-column-span/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-areas-config/manifests.ts Updates manifest group to Common.
src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-area-type-permission/manifests.ts Updates manifest group to Common.

You can also share your feedback on Copilot code review. Take the survey.

@madsrasmussen

Copy link
Copy Markdown
Member

Hi,

I was thinking about whether it would make sense to prefix all the group aliases with a # instead, and then run them through the localization registry? If I remember correctly, it will return the input text if it can’t find a translation. This way, we get localized group names and do not change the package ones 🤔

@AndyButland

Copy link
Copy Markdown
Contributor Author

That sounds a good idea @madsrasmussen. Though we'd need to keep supporting packages that don't provide localized group names. So would you suggest:

  • Add translation keys for all the core groups.
  • Update all the core property editors to use localization keys, e.g.:
meta: {
	label: 'Markdown Editor',
	propertyEditorSchemaAlias: 'Umbraco.MarkdownEditor',
	icon: 'icon-code',
	group: '#richContent',
  • Update the code that now calls fromCamelCaseIfCamelCase(propertyEditorUi.meta.group ?? 'Uncategorized'), to only call this if the provided group isn't prefixed with #. If it is, instead localize it.

@madsrasmussen

Copy link
Copy Markdown
Member

@AndyButland If we use the localize.string method, it will try to localize any word in the string with a # prefix. Anything that is not prefixed will be returned "as is". So, if we run "My CusTom UI Group" through it, it should return the same: "My CusTom UI Group."

@AndyButland

Copy link
Copy Markdown
Contributor Author

@madsrasmussen - my concern though was groups provided by packages that previously were converted from camel case, would now no longer be. So if someone had a group of "myGroup", currently this will be displayed as "My Group" as we run it through the fromCamelCase function. But if we stop doing that, expecting that it'll be localised, it'll be displayed as is, so as "myGroup".

@madsrasmussen

Copy link
Copy Markdown
Member

@AndyButland Ah, yeah, then I think it's an ok solution you proposed, so we are backwards compatible

@AndyButland

Copy link
Copy Markdown
Contributor Author

Thanks @madsrasmussen - I've prepared that now:

image

@nielslyngsoe

Copy link
Copy Markdown
Member

I skimmed the changes, looks good, just needs a final review by someone :-)

@AndyButland
AndyButland changed the base branch from main to v17/dev May 8, 2026 09:13
@AndyButland
AndyButland force-pushed the v17/bugfix/22189-use-provided-property-editor-ui-group-names branch from 2758f88 to dbbbca4 Compare May 8, 2026 09:36
@nielslyngsoe
nielslyngsoe removed the request for review from madsrasmussen May 11, 2026 07:12
@nielslyngsoe nielslyngsoe added the state/sprint-candidate We're trying to get this in a sprint at HQ in the next few weeks label May 11, 2026
@nielslyngsoe
nielslyngsoe enabled auto-merge (squash) May 13, 2026 07:17
@AndyButland
AndyButland disabled auto-merge May 13, 2026 09:06
@nielslyngsoe
nielslyngsoe merged commit 0add0f5 into v17/dev May 13, 2026
30 checks passed
@nielslyngsoe
nielslyngsoe deleted the v17/bugfix/22189-use-provided-property-editor-ui-group-names branch May 13, 2026 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/frontend category/ux User experience release/17.6.0 release/18.1.0 state/sprint-candidate We're trying to get this in a sprint at HQ in the next few weeks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants