Merge branch 'main' into v17/dev

# Conflicts:
#	src/Umbraco.Web.UI.Client/src/packages/content/property-type/workspace/views/settings/property-workspace-view-settings.element.ts
This commit is contained in:
Niels Lyngsø
2025-10-28 11:20:03 +01:00
6 changed files with 71 additions and 23 deletions

8
.github/README.md vendored
View File

@@ -38,6 +38,14 @@ Some important documentation links to get you started:
- [Getting to know Umbraco](https://docs.umbraco.com/umbraco-cms/fundamentals/get-to-know-umbraco)
- [Tutorials for creating a basic website and customizing the editing experience](https://docs.umbraco.com/umbraco-cms/tutorials/overview)
## Backoffice Preview
Want to see the latest backoffice UI in action? Check out our live preview:
**[backofficepreview.umbraco.com](https://backofficepreview.umbraco.com/)**
This preview is automatically deployed from the main branch and showcases the latest backoffice features and improvements. It runs from mock data and persistent edits are not supported.
## Get help
If you need a bit of feedback while building your Umbraco projects, we are [chatty on Discord](https://discord.umbraco.com). Our Discord server serves as a social space for all Umbracians. If you have any questions or need some help with a problem, head over to our [dedicated forum](https://forum.umbraco.com/) where the Umbraco Community will be happy to help.

View File

@@ -175,7 +175,7 @@ internal sealed class MediaTypeEditingService : ContentTypeEditingServiceBase<IM
continue;
}
allowedFileExtensionsByMediaType[mediaType] = fileUploadConfiguration.FileExtensions;
allowedFileExtensionsByMediaType[mediaType] = fileUploadConfiguration.FileExtensions ?? []; // Although we never expect null here, legacy data type configuration did allow it.
}
return allowedFileExtensionsByMediaType;

View File

@@ -2,6 +2,14 @@
This package contains the types for the Umbraco Backoffice.
## Preview
A live preview of the latest backoffice build from the main branch is available at:
**[backofficepreview.umbraco.com](https://backofficepreview.umbraco.com/)**
This preview is automatically deployed via GitHub Actions whenever changes are pushed to main or version branches.
## Installation
```bash

View File

@@ -30,6 +30,9 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPicker
@state()
private _colorList = umbracoColors.filter((color) => !color.legacy);
@state()
private _isSearching = false;
constructor() {
super();
this.consumeContext(UMB_ICON_REGISTRY_CONTEXT, (context) => {
@@ -44,8 +47,10 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPicker
if (!this.#icons) return;
const value = this._searchInput?.value;
if (value) {
this._isSearching = value.length > 0;
this._iconsFiltered = this.#icons.filter((icon) => icon.name.toLowerCase().includes(value.toLowerCase()));
} else {
this._isSearching = false;
this._iconsFiltered = this.#icons;
}
}
@@ -54,8 +59,12 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPicker
const isActivate = e.type === 'click' || (e.type === 'keyup' && (e as KeyboardEvent).key === 'Enter');
if (!isActivate) return;
const nextIcon = this.value.icon === iconName ? '' : iconName;
this.modalContext?.updateValue({ icon: nextIcon });
if (this.data?.showEmptyOption) {
const nextIcon = this.value.icon === iconName ? '' : iconName;
this.modalContext?.updateValue({ icon: nextIcon });
} else {
this.modalContext?.updateValue({ icon: iconName });
}
}
#onColorChange(e: UUIColorSwatchesEvent) {
@@ -93,16 +102,21 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement<UmbIconPicker
</uui-color-swatches>
<hr />
<uui-scroll-container id="icons">
<uui-button
class=${!this.value.icon ? 'selected' : ''}
label=${this.localize.term('defaultdialogs_noIcon')}
title=${this.localize.term('defaultdialogs_noIcon')}
@click=${this.#clearIcon}
@keyup=${(e: KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') this.#clearIcon();
}}>
<uui-icon style="opacity:.35" name=${ifDefined(this.data?.placeholder)}></uui-icon> </uui-button
>${this.renderIcons()}</uui-scroll-container
${this.data?.showEmptyOption && !this._isSearching
? html`
<uui-button
class=${!this.value.icon ? 'selected' : ''}
label=${this.localize.term('defaultdialogs_noIcon')}
title=${this.localize.term('defaultdialogs_noIcon')}
@click=${this.#clearIcon}
@keyup=${(e: KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') this.#clearIcon();
}}>
<uui-icon style="opacity:.35" name=${ifDefined(this.data?.placeholder)}></uui-icon>
</uui-button>
`
: nothing}
${this.renderIcons()}</uui-scroll-container
>
</div>
<uui-button

View File

@@ -2,6 +2,7 @@ import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
export interface UmbIconPickerModalData {
placeholder?: string;
showEmptyOption?: boolean;
}
export interface UmbIconPickerModalValue {

View File

@@ -9,28 +9,45 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { extractUmbColorVariable } from '@umbraco-cms/backoffice/resources';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation';
/**
* @element umb-property-editor-ui-icon-picker
*/
@customElement('umb-property-editor-ui-icon-picker')
export class UmbPropertyEditorUIIconPickerElement extends UmbLitElement implements UmbPropertyEditorUiElement {
//
export class UmbPropertyEditorUIIconPickerElement
extends UmbFormControlMixin<string, typeof UmbLitElement, undefined>(UmbLitElement, undefined)
implements UmbPropertyEditorUiElement
{
@property({ type: Boolean })
mandatory = false;
protected override firstUpdated(): void {
this.addValidator(
'valueMissing',
() => 'Icon is required',
() => this.mandatory && !this._icon,
);
}
@property()
public set value(v: string) {
this._value = v ?? '';
const parts = this._value.split(' ');
public override set value(v: string) {
const val = v ?? '';
super.value = val;
const parts = val.split(' ');
if (parts.length === 2) {
this._icon = parts[0];
this._color = parts[1].replace('color-', '');
} else {
this._icon = this._value;
this._icon = val;
this._color = '';
}
}
public get value() {
return this._value;
public override get value() {
return (super.value as string) ?? '';
}
private _value = '';
@state()
private _icon = '';
@@ -53,7 +70,7 @@ export class UmbPropertyEditorUIIconPickerElement extends UmbLitElement implemen
icon: this._icon,
color: this._color,
},
data: { placeholder: this._placeholderIcon },
data: { placeholder: this._placeholderIcon, showEmptyOption: !this.mandatory },
}).catch(() => undefined);
if (!data) return;