Skip to content
This repository was archived by the owner on Nov 6, 2025. It is now read-only.

Commit 58cb314

Browse files
authored
Merge pull request #2167 from umbraco/v14/feature/block-type-custom-view-guide
Block type custom view guide
2 parents 3e0a9a3 + 30ce4c0 commit 58cb314

File tree

557 files changed

+881
-677
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

557 files changed

+881
-677
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@
254254
"eslint-plugin-wc": "^2.1.0",
255255
"glob": "^11.0.0",
256256
"globals": "^15.8.0",
257-
"lucide-static": "^0.408.0",
257+
"lucide-static": "^0.424.0",
258258
"msw": "^1.3.2",
259259
"playwright-msw": "^3.0.1",
260260
"prettier": "3.3.3",

src/assets/lang/en-us.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,7 @@ export default {
820820
logout: 'Logout',
821821
macro: 'Macro',
822822
mandatory: 'Mandatory',
823+
manifest: 'Manifest',
823824
media: 'Media',
824825
message: 'Message',
825826
move: 'Move',
@@ -2403,6 +2404,7 @@ export default {
24032404
tabClipboard: 'Clipboard',
24042405
tabBlockSettings: 'Settings',
24052406
headlineAdvanced: 'Advanced',
2407+
headlineCustomView: 'Custom View',
24062408
forceHideContentEditor: 'Hide content editor',
24072409
forceHideContentEditorHelp: 'Hide the content edit button and the content editor from the Block Editor overlay',
24082410
gridInlineEditing: 'Inline editing',

src/assets/lang/en.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,7 @@ export default {
831831
logout: 'Logout',
832832
macro: 'Macro',
833833
mandatory: 'Mandatory',
834+
manifest: 'Manifest',
834835
message: 'Message',
835836
move: 'Move',
836837
name: 'Name',
@@ -2471,6 +2472,7 @@ export default {
24712472
tabClipboard: 'Clipboard',
24722473
tabBlockSettings: 'Settings',
24732474
headlineAdvanced: 'Advanced',
2475+
headlineCustomView: 'Custom View',
24742476
forceHideContentEditor: 'Hide content editor',
24752477
forceHideContentEditorHelp: 'Hide the content edit button and the content editor from the Block Editor overlay.',
24762478
gridInlineEditing: 'Inline editing',

src/packages/block/block-grid/components/block-grid-entries/block-grid-entries.element.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,6 @@ export class UmbBlockGridEntriesElement extends UmbFormControlMixin(UmbLitElemen
292292
if (this._areaKey === null || this._layoutEntries.length === 0) {
293293
return html`<uui-button-group>
294294
<uui-button
295-
id="add-button"
296295
look="placeholder"
297296
label=${this._singleBlockTypeName
298297
? this.localize.term('blockEditor_addThis', [this._singleBlockTypeName])

src/packages/block/block-grid/property-editors/block-grid-areas-config/property-editor-ui-block-grid-areas-config.element.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ export class UmbPropertyEditorUIBlockGridAreasConfigElement
128128
)}
129129
</div>
130130
<uui-button
131-
id="add-button"
132131
look="placeholder"
133132
label=${'Add area'}
134133
href=${this._workspacePath + 'create'}></uui-button>`

src/packages/block/block-grid/workspace/views/block-grid-type-workspace-view-advanced.element.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import { UMB_BLOCK_GRID } from '../../types.js';
12
import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit';
23
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
34
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
45
import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/extension-registry';
6+
// Getting umb-block-type-custom-view-guide element
7+
import '@umbraco-cms/backoffice/block-type';
58

69
@customElement('umb-block-grid-type-workspace-view-advanced')
710
export class UmbBlockGridTypeWorkspaceViewAdvancedElement extends UmbLitElement implements UmbWorkspaceViewElement {
@@ -21,6 +24,13 @@ export class UmbBlockGridTypeWorkspaceViewAdvancedElement extends UmbLitElement
2124
alias="hideContentEditor"
2225
property-editor-ui-alias="Umb.PropertyEditorUi.Toggle"></umb-property>
2326
</uui-box>
27+
<uui-box headline=${this.localize.term('blockEditor_headlineCustomView')}>
28+
<umb-property-layout label=${this.localize.term('blockEditor_labelCustomView')}>
29+
<umb-block-type-custom-view-guide
30+
slot="editor"
31+
block-editor-type=${UMB_BLOCK_GRID}></umb-block-type-custom-view-guide>
32+
</umb-property-layout>
33+
</uui-box>
2434
<uui-box headline=${this.localize.term('blockEditor_headlineCatalogueAppearance')}>
2535
<umb-property
2636
label=${this.localize.term('blockEditor_labelBackgroundColor')}

src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,7 @@ export class UmbPropertyEditorUIBlockListElement extends UmbLitElement implement
175175
</umb-block-list-entry> `,
176176
)}
177177
<uui-button-group>
178-
<uui-button
179-
id="add-button"
180-
look="placeholder"
181-
label=${this._createButtonLabel}
182-
href=${createPath ?? ''}></uui-button>
178+
<uui-button look="placeholder" label=${this._createButtonLabel} href=${createPath ?? ''}></uui-button>
183179
<uui-button
184180
label=${this.localize.term('content_createFromClipboard')}
185181
look="placeholder"
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
2+
import { html, customElement, state, property, css } from '@umbraco-cms/backoffice/external/lit';
3+
import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property';
4+
import {
5+
UMB_MANIFEST_VIEWER_MODAL,
6+
umbExtensionsRegistry,
7+
type ManifestBlockEditorCustomView,
8+
} from '@umbraco-cms/backoffice/extension-registry';
9+
import { stringOrStringArrayContains } from '@umbraco-cms/backoffice/utils';
10+
import { UmbExtensionsManifestInitializer } from '@umbraco-cms/backoffice/extension-api';
11+
import { UmbDocumentTypeDetailRepository } from '@umbraco-cms/backoffice/document-type';
12+
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
13+
14+
@customElement('umb-block-type-custom-view-guide')
15+
export class UmbBlockTypeCustomViewGuideElement extends UmbLitElement {
16+
#contentTypeName?: string;
17+
#contentTypeAlias?: string;
18+
#blockEditorType?: string;
19+
20+
@property({ type: String, attribute: 'block-editor-type' })
21+
get blockEditorType() {
22+
return this.#blockEditorType;
23+
}
24+
set blockEditorType(value) {
25+
this.#blockEditorType = value;
26+
this.#loadManifests();
27+
}
28+
29+
@state()
30+
private _manifests?: Array<ManifestBlockEditorCustomView>;
31+
32+
#repository = new UmbDocumentTypeDetailRepository(this);
33+
34+
constructor() {
35+
super();
36+
37+
this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, async (context) => {
38+
this.observe(
39+
await context.propertyValueByAlias<string | undefined>('contentElementTypeKey'),
40+
async (value) => {
41+
if (!value) return;
42+
const { asObservable } = await this.#repository.requestByUnique(value);
43+
this.observe(
44+
asObservable(),
45+
(model) => {
46+
this.#contentTypeName = model?.name;
47+
this.#contentTypeAlias = model?.alias;
48+
this.#loadManifests();
49+
},
50+
'observeContentType',
51+
);
52+
},
53+
'observeContentElementTypeKey',
54+
);
55+
});
56+
}
57+
58+
#loadManifests() {
59+
if (!this.#blockEditorType || !this.#contentTypeAlias) return;
60+
new UmbExtensionsManifestInitializer(
61+
this,
62+
umbExtensionsRegistry,
63+
'blockEditorCustomView',
64+
this.#extensionFilterMethod,
65+
async (customViews) => {
66+
this._manifests = customViews.map((x) => x.manifest);
67+
},
68+
'manifestInitializer',
69+
);
70+
}
71+
72+
#extensionFilterMethod = (manifest: ManifestBlockEditorCustomView) => {
73+
if (!this.#blockEditorType || !this.#contentTypeAlias) return false;
74+
if (
75+
manifest.forContentTypeAlias &&
76+
!stringOrStringArrayContains(manifest.forContentTypeAlias, this.#contentTypeAlias!)
77+
) {
78+
return false;
79+
}
80+
if (manifest.forBlockEditor && !stringOrStringArrayContains(manifest.forBlockEditor, this.#blockEditorType)) {
81+
return false;
82+
}
83+
return true;
84+
};
85+
86+
async #viewManifest(manifest: ManifestBlockEditorCustomView) {
87+
const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
88+
modalManager.open(this, UMB_MANIFEST_VIEWER_MODAL, { data: manifest });
89+
}
90+
91+
async #generateManifest() {
92+
const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);
93+
94+
const manifest = {
95+
type: 'blockEditorCustomView',
96+
alias: 'Local.blockEditorCustomView.' + this.#contentTypeAlias,
97+
name: 'Block Editor Custom View for ' + this.#contentTypeName,
98+
element: '[replace with path to your web component js file...]',
99+
forContentTypeAlias: this.#contentTypeAlias,
100+
forBlockEditor: this.#blockEditorType,
101+
};
102+
modalManager.open(this, UMB_MANIFEST_VIEWER_MODAL, { data: manifest });
103+
}
104+
105+
override render() {
106+
return this._manifests && this._manifests.length > 0
107+
? html` <div>
108+
<umb-ref-manifest
109+
standalone
110+
@open=${() => this.#viewManifest(this._manifests![0])}
111+
.manifest=${this._manifests[0]}></umb-ref-manifest>
112+
</div>`
113+
: html`<uui-button
114+
id="add-button"
115+
look="placeholder"
116+
label="Generate manifest for this Block Type"
117+
type="button"
118+
color="default"
119+
@click=${() => this.#generateManifest()}></uui-button>`;
120+
}
121+
122+
static override styles = [
123+
css`
124+
#add-button {
125+
text-align: center;
126+
width: 100%;
127+
}
128+
`,
129+
];
130+
}
131+
132+
export default UmbBlockTypeCustomViewGuideElement;
133+
134+
declare global {
135+
interface HTMLElementTagNameMap {
136+
'umb-block-type-custom-view-guide': UmbBlockTypeCustomViewGuideElement;
137+
}
138+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './block-type-card/index.js';
22
export * from './input-block-type/index.js';
3+
export * from './block-type-custom-view-guide/block-type-custom-view-guide.element.js';

0 commit comments

Comments
 (0)