Skip to content

Commit 43d56b0

Browse files
committed
Revamp "Menus" documentation: updated examples to align with new JSON schema and TypeScript imports. Removed outdated code and restructured sections for clarity and consistency.
1 parent 08d3e10 commit 43d56b0

File tree

1 file changed

+56
-154
lines changed
  • 16/umbraco-cms/customizing/extending-overview/extension-types

1 file changed

+56
-154
lines changed

16/umbraco-cms/customizing/extending-overview/extension-types/menu.md

Lines changed: 56 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,16 @@ Menu extensions can be created using either JSON or TypeScript. Both approaches
1818
{% code title="umbraco-package.json" %}
1919
```json
2020
{
21-
"type": "menu",
22-
"alias": "My.Menu",
23-
"name": "My Menu"
21+
"$schema": "../../umbraco-package-schema.json",
22+
"name": "My Package",
23+
"version": "0.1.0",
24+
"extensions": [
25+
{
26+
"type": "menu",
27+
"alias": "My.Menu",
28+
"name": "My Menu"
29+
}
30+
]
2431
}
2532
```
2633
{% endcode %}
@@ -32,13 +39,11 @@ Extension authors define the menu manifest, then register it dynamically/during
3239
```typescript
3340
import type { ManifestMenu } from '@umbraco-cms/backoffice/menu';
3441

35-
export const menuManifest: Array<ManifestMenu> = [
36-
{
37-
type: 'menu',
38-
alias: 'My.Menu',
39-
name: 'My Menu'
40-
}
41-
];
42+
export const menuManifest: ManifestMenu = {
43+
type: 'menu',
44+
alias: 'My.Menu',
45+
name: 'My Menu'
46+
};
4247
```
4348
{% endcode %}
4449

@@ -79,14 +84,21 @@ To add custom menu items, you can define a single MenuItem manifest and link an
7984
{% code title="umbraco-package.json" %}
8085
```json
8186
{
82-
"type": "menuItem",
83-
"alias": "My.MenuItem",
84-
"name": "My Menu Item",
85-
"element": "./menu-items.ts",
86-
"meta": {
87-
"label": "My Menu Item",
88-
"menus": ["My.Menu"]
89-
}
87+
"$schema": "../../umbraco-package-schema.json",
88+
"name": "My Package",
89+
"version": "0.1.0",
90+
"extensions": [
91+
{
92+
"type": "menuItem",
93+
"alias": "My.MenuItem",
94+
"name": "My Menu Item",
95+
"element": "./menu-items.ts",
96+
"meta": {
97+
"label": "My Menu Item",
98+
"menus": ["My.Menu"]
99+
}
100+
}
101+
]
90102
}
91103
```
92104
{% hint style="info" %}
@@ -102,17 +114,17 @@ The `element` attribute will point toward a custom Lit component, an example of
102114

103115
{% code title="my-menu/manifests.ts" %}
104116
```typescript
105-
const menuItemManifest: Array<ManifestMenuItem> = [
106-
{
107-
type: 'menuItem',
108-
alias: 'My.MenuItem',
109-
name: 'My Menu Item',
110-
meta: {
111-
label: 'My Menu Item',
112-
menus: ["My.Menu"]
113-
},
114-
}
115-
];
117+
import type { ManifestMenuItem } from '@umbraco-cms/backoffice/menu';
118+
119+
export const menuItemManifest: ManifestMenuItem = {
120+
type: 'menuItem',
121+
alias: 'My.MenuItem',
122+
name: 'My Menu Item',
123+
meta: {
124+
label: 'My Menu Item',
125+
menus: ["My.Menu"]
126+
},
127+
};
116128
```
117129
{% endcode %}
118130

@@ -134,123 +146,6 @@ export const onInit: UmbEntryPointOnInit = (_host, _extensionRegistry) => {
134146
{% endtab %}
135147
{% endtabs %}
136148

137-
### Custom menu items
138-
139-
{% hint style="info" %}
140-
**Note:** Displaying menu item extensions does not require extension authors to create custom menu item subclasss. This step is optional.
141-
{% endhint %}
142-
143-
To render your menu items in Umbraco, extension authors can use the [Umbraco UI Menu Item component](https://uui.umbraco.com/?path=/docs/uui-menu-item--docs). This component enables nested menu structures with a few lines of markup.
144-
145-
`<uui-menu-item>` nodes accept the `has-children` boolean attribute, which will display a caret icon indicating nested items. Tying this boolean attribute to a variable requires using the `?` Lit directive, which would look similar to this: `?has-children=${boolVariable}`.
146-
147-
**Example:**
148-
149-
```html
150-
<uui-menu-item label="Menu Item 1" has-children>
151-
<uui-menu-item label="Nested Menu Item 1"></uui-menu-item>
152-
<uui-menu-item label="Nested Menu Item 2"></uui-menu-item>
153-
</uui-menu-item>
154-
```
155-
156-
### Custom menu item element example
157-
158-
Custom elements can fetch the data and render menu items using markup, like above. Storing the results of the fetch in a `@state()` variable will trigger a re-render of the component when the value of the variable changes.
159-
160-
{% code title="menu-items.ts" overflow="wrap" lineNumbers="true" %}
161-
```typescript
162-
import type { UmbMenuItemElement } from '@umbraco-cms/backoffice/menu';
163-
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
164-
import { html, TemplateResult, customElement, state } from '@umbraco-cms/backoffice/external/lit';
165-
import { MyMenuItemResponseModel, MyMenuResource } from '../../../api';
166-
167-
const elementName = 'my-menu-item';
168-
169-
@customElement(elementName)
170-
class MyMenuItems extends UmbLitElement implements UmbMenuItemElement {
171-
@state()
172-
private _items: MyMenuItemResponseModel[] = []; // Store fetched items
173-
174-
@state()
175-
private _loading: boolean = true; // Track loading state
176-
177-
@state()
178-
private _error: string | null = null; // Track any errors
179-
180-
override firstUpdated() {
181-
this.fetchInitialItems(); // Start fetching on component load
182-
}
183-
184-
// Fetch initial items
185-
async fetchInitialItems() {
186-
try {
187-
this._loading = true;
188-
this._items = ((await MyMenuResource.getMenuApiV1()).items); // Fetch root-level items
189-
} catch (e) {
190-
this._error = 'Error fetching items';
191-
} finally {
192-
this._loading = false;
193-
}
194-
}
195-
196-
// Render items
197-
renderItems(items: MyMenuItemResponseModel[]): TemplateResult {
198-
return html`
199-
${items.map(element => html`
200-
<uui-menu-item label="${element.name}" ?has-children=${element.hasChildren}>
201-
${element.type === 1
202-
? html`<uui-icon slot="icon" name="icon-folder"></uui-icon>`
203-
: html`<uui-icon slot="icon" name="icon-autofill"></uui-icon>`}
204-
<!-- recursively render children -->
205-
${element.hasChildren ? this.renderItems(element.children) : ''}
206-
</uui-menu-item>
207-
`)}
208-
`;
209-
}
210-
211-
// Main render function
212-
override render() {
213-
if (this._loading) {
214-
return html`<uui-loader></uui-loader>`;
215-
}
216-
217-
if (this._error) {
218-
return html`<uui-menu-item active disabled label="Could not load form tree!">
219-
</uui-menu-item>`;
220-
}
221-
222-
// Render items if loading is done and no error occurred
223-
return this.renderItems(this._items);
224-
}
225-
}
226-
227-
export { MyMenuItems as element };
228-
229-
declare global {
230-
interface HTMLElementTagNameMap {
231-
[elementName]: MyMenuItems;
232-
}
233-
}
234-
```
235-
{% endcode %}
236-
237-
## Tree Menu Item
238-
239-
### Manifest
240-
241-
```json
242-
{
243-
"type": "menuItem",
244-
"kind": "tree",
245-
"alias": "My.TreeMenuItem",
246-
"name": "My Tree Menu Item",
247-
"meta": {
248-
"label": "My Tree Menu Item",
249-
"menus": ["My.Menu"]
250-
}
251-
}
252-
```
253-
254149
#### Default Element
255150

256151
The default element supports rendering a subtree of menu items.
@@ -282,14 +177,21 @@ To add a menu item to an existing menu, use the `meta.menus` property.
282177
{% code title="umbraco-package.json" %}
283178
```json
284179
{
285-
"type": "menuItem",
286-
"alias": "My.MenuItem",
287-
"name": "My Menu Item",
288-
"meta": {
289-
"label": "My Menu Item",
290-
"menus": ["Umb.Menu.Content"]
291-
},
292-
"element": "menu-items.js"
180+
"$schema": "../../umbraco-package-schema.json",
181+
"name": "My Package",
182+
"version": "0.1.0",
183+
"extensions": [
184+
{
185+
"type": "menuItem",
186+
"alias": "My.MenuItem",
187+
"name": "My Menu Item",
188+
"meta": {
189+
"label": "My Menu Item",
190+
"menus": ["Umb.Menu.Content"]
191+
},
192+
"element": "menu-items.js"
193+
}
194+
]
293195
}
294196
```
295197
{% endcode %}

0 commit comments

Comments
 (0)