general-add-value-summary

star 5.2k

Add a value summary extension so a feature's typed value can be displayed compactly in collection views (e.g., table columns). Use when a feature or property editor already has a value type and needs a renderer for collection table cells. Two variants — simple (element only, no API call) and resolver (batch API resolution needed). Prerequisite: a value type constant must already exist — use the general-add-value-type skill first if it doesn't.

umbraco By umbraco schedule Updated 5/6/2026

name: general-add-value-summary description: Add a value summary extension so a feature's typed value can be displayed compactly in collection views (e.g., table columns). Use when a feature or property editor already has a value type and needs a renderer for collection table cells. Two variants — simple (element only, no API call) and resolver (batch API resolution needed). Prerequisite: a value type constant must already exist — use the general-add-value-type skill first if it doesn't. allowed-tools: Read, Write, Edit, Grep, Glob

Add Value Summary

Add a valueSummary extension so a feature's values are rendered in collection views.

Foundational documentation

Read before proceeding:

  • Value Summary — extension type, base classes, resolver contract, rules

Prerequisite

A value type constant (UMB_{FEATURE}_VALUE_TYPE) must already exist and be exported from the package index.ts. If it doesn't exist yet, use the general-add-value-type skill first.

What you need from the user

  1. Feature name — kebab-case (e.g., color-picker, user-group)
  2. Package path — where the feature lives (e.g., src/packages/property-editors/color-picker/)
  3. Value type constant — the existing constant to bind to (e.g., UMB_COLOR_PICKER_VALUE_TYPE)
  4. Resolver needed? — Yes if rendering requires an API call (resolving IDs to names). No if the raw value can be formatted directly.

If resolver is needed, also ask: 5. Resolved type — the TypeScript type after resolution (e.g., UmbUserGroupItemModel) 6. Repository to use — which item/detail repository resolves the values


Option A: Simple summary (no resolver)

Use when the raw value can be formatted or rendered without an API call — dates, booleans, strings, color hex codes, numeric ranges, etc.

Files to create

{package-path}/value-summary/
├── manifests.ts
└── {feature}-value-summary.element.ts

Step 1: Create the summary element

File: {package-path}/value-summary/{feature}-value-summary.element.ts

import { customElement, html } from '@umbraco-cms/backoffice/external/lit';
import { UmbValueSummaryElementBase } from '@umbraco-cms/backoffice/value-summary';

@customElement('umb-{feature}-value-summary')
export class Umb{Feature}ValueSummaryElement extends UmbValueSummaryElementBase<{TValue}> {
    override render() {
        if (!this._value) return html``;
        return html`<span>${this._value}</span>`;
    }
}

export { Umb{Feature}ValueSummaryElement as element };

declare global {
    interface HTMLElementTagNameMap {
        ['umb-{feature}-value-summary']: Umb{Feature}ValueSummaryElement;
    }
}

Adjust render() for the value type:

  • Dates → this.localize.dateTime(value)
  • Booleans → <umb-icon>
  • References → tags or comma-separated names

Step 2: Create the manifest

File: {package-path}/value-summary/manifests.ts

import type { UmbExtensionManifest } from '@umbraco-cms/backoffice/extension-api';
import { UMB_{FEATURE}_VALUE_TYPE } from '../value-type/constants.js';

export const manifests: Array<UmbExtensionManifest> = [
    {
        type: 'valueSummary',
        kind: 'default',
        alias: 'Umb.ValueSummary.{Feature}',
        name: '{Feature} Value Summary',
        forValueType: UMB_{FEATURE}_VALUE_TYPE,
        element: () => import('./{feature}-value-summary.element.js'),
    },
];

Step 3: Wire manifests into parent

import { manifests as valueSummaryManifests } from './value-summary/manifests.js';

export const manifests: Array<UmbExtensionManifest> = [
    ...valueSummaryManifests,
    // ... other manifests
];

Simple summary checklist

  • Element extends UmbValueSummaryElementBase and exports as element
  • Manifest uses kind: 'default', correct forValueType, lazy element import
  • Manifests wired into parent manifests.ts
  • Compiles: npm run compile

Option B: Summary with resolver (batch API resolution)

Use when displaying the value requires fetching data — e.g., resolving reference uniques to display names. The resolver receives all values from the entire column in one batch call.

Files to create

{package-path}/value-summary/
├── manifests.ts
├── {feature}-value-summary.element.ts
└── {feature}-value-summary.resolver.ts

Step 1: Create the summary element

Same pattern as Option A, Step 1. Pass {TResolved} as the generic instead of {TValue} — the element receives the resolved value in this._value, already correctly typed.

Step 2: Create the resolver

File: {package-path}/value-summary/{feature}-value-summary.resolver.ts

import type { UmbValueSummaryResolver } from '@umbraco-cms/backoffice/value-summary';
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import { Umb{Entity}ItemRepository } from '../repository/item/{entity}-item.repository.js';

export class Umb{Feature}ValueSummaryResolver
    extends UmbControllerBase
    implements UmbValueSummaryResolver<{TValue}, {TResolved}>
{
    #repo = new Umb{Entity}ItemRepository(this);

    async resolveValues(values: ReadonlyArray<{TValue}>) {
        // Deduplicate all IDs needed across the entire batch
        const allUniques = [...new Set(values.flatMap((v) => /* extract IDs from v */))];

        const { data: items, asObservable } = await this.#repo.requestItems(allUniques);
        if (!items) return { data: values.map(() => undefined as unknown as {TResolved}) };

        // Positional mapping — output must align with input
        return {
            data: values.map((v) => /* find resolved item(s) for v */),
            asObservable: asObservable
                ? () => asObservable().pipe(map((latest) => values.map((v) => /* remap */)))
                : undefined,
        };
    }
}

export { Umb{Feature}ValueSummaryResolver as valueResolver };

Critical rules:

  • data must have the same length as values and be positionally aligned.
  • Export the class as valueResolver (named export) — the loader checks for this name.
  • Provide asObservable only when the resolved data can change after initial load.

Step 3: Create the manifest

File: {package-path}/value-summary/manifests.ts

import type { UmbExtensionManifest } from '@umbraco-cms/backoffice/extension-api';
import { UMB_{FEATURE}_VALUE_TYPE } from '../value-type/constants.js';

export const manifests: Array<UmbExtensionManifest> = [
    {
        type: 'valueSummary',
        kind: 'default',
        alias: 'Umb.ValueSummary.{Feature}',
        name: '{Feature} Value Summary',
        forValueType: UMB_{FEATURE}_VALUE_TYPE,
        element: () => import('./{feature}-value-summary.element.js'),
        valueResolver: () => import('./{feature}-value-summary.resolver.js'),
    },
];

Step 4: Wire manifests into parent

Same as Option A, Step 3.

Resolver checklist

  • Element extends UmbValueSummaryElementBase, renders resolved type, exports as element
  • Resolver extends UmbControllerBase, implements UmbValueSummaryResolver<{TValue}, {TResolved}>
  • resolveValues() returns data positionally aligned with values (same length, same order)
  • Resolver exported as valueResolver (named export)
  • Manifest includes valueResolver: () => import(...) lazy loader
  • asObservable included only if resolved data can change reactively
  • Manifests wired into parent manifests.ts
  • Compiles: npm run compile

Collection wiring

Property editors: no extra step needed. The document collection reads editorAlias from the server and matches it to your forValueType.

Generic table collection kind: set valueType in the collection manifest column:

{ field: 'myField', label: 'My Field', valueType: UMB_{FEATURE}_VALUE_TYPE }
Install via CLI
npx skills add https://github.com/umbraco/Umbraco-CMS --skill general-add-value-summary
Repository Details
star Stars 5,199
call_split Forks 2,882
navigation Branch main
article Path SKILL.md
More from Creator