diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts index f25516b690..bc375af6de 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts @@ -822,6 +822,7 @@ export default { error: 'Error', field: 'Field', fieldFor: 'Field for %0%', + toggleFor: 'Toggle for %0%', findDocument: 'Find', first: 'First', focalPoint: 'Focal point', diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts index d09cfb9991..481d1c2744 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -372,6 +372,8 @@ export default { fileSecurityValidationFailure: 'One or more file security validations have failed', moveToSameFolderFailed: 'Parent and destination folders cannot be the same', uploadNotAllowed: 'Upload is not allowed in this location.', + noticeExtensionsServerOverride: + 'Regardless of the allowed file types, the following limitations apply system-wide due to the server configuration:', }, member: { '2fa': 'Two-Factor Authentication', @@ -817,6 +819,7 @@ export default { error: 'Error', field: 'Field', fieldFor: 'Field for %0%', + toggleFor: 'Toggle for %0%', findDocument: 'Find', first: 'First', focalPoint: 'Focal point', @@ -885,6 +888,7 @@ export default { retrieve: 'Retrieve', retry: 'Retry', rights: 'Permissions', + serverConfiguration: 'Server Configuration', scheduledPublishing: 'Scheduled Publishing', umbracoInfo: 'Umbraco info', search: 'Search', @@ -2138,6 +2142,9 @@ export default { numberMinimum: "Value must be greater than or equal to '%0%'.", numberMaximum: "Value must be less than or equal to '%0%'.", numberMisconfigured: "Minimum value '%0%' must be less than the maximum value '%1%'.", + invalidExtensions: 'One or more of the extensions are invalid.', + allowedExtensions: 'Allowed extensions are:', + disallowedExtensions: 'Disallowed extensions are:', }, healthcheck: { checkSuccessMessage: "Value is set to the recommended value: '%0%'.", diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-toggle/input-toggle.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-toggle/input-toggle.element.ts index 58249d3659..e13327c900 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-toggle/input-toggle.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-toggle/input-toggle.element.ts @@ -26,6 +26,9 @@ export class UmbInputToggleElement extends UUIFormControlMixin(UmbLitElement, '' @property({ type: String }) labelOff?: string; + @property({ type: String, attribute: 'aria-label' }) + override ariaLabel: string | null = null; + /** * Sets the input to readonly mode, meaning value cannot be changed but still able to read and select its content. * @type {boolean} @@ -42,6 +45,8 @@ export class UmbInputToggleElement extends UUIFormControlMixin(UmbLitElement, '' return undefined; } + // test + override connectedCallback(): void { super.connectedCallback(); this.#updateLabel(); @@ -54,15 +59,15 @@ export class UmbInputToggleElement extends UUIFormControlMixin(UmbLitElement, '' } #updateLabel() { - this._currentLabel = this.showLabels ? (this.checked ? this.labelOn : this.labelOff) : ''; + this._currentLabel = this.showLabels ? (this.checked ? this.labelOn : this.labelOff) : ''; } override render() { return html``; + ?readonly=${this.readonly}>${this._currentLabel} `; } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/multiple-text-string-input/input-multiple-text-string-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/multiple-text-string-input/input-multiple-text-string-item.element.ts index d2f07b510f..aca689e71c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/multiple-text-string-input/input-multiple-text-string-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/multiple-text-string-input/input-multiple-text-string-item.element.ts @@ -65,12 +65,12 @@ export class UmbInputMultipleTextStringItemElement extends UUIFormControlMixin(U } // Prevent valid events from bubbling outside the message element - #onValid(event: any) { + #onValid(event: Event) { event.stopPropagation(); } // Prevent invalid events from bubbling outside the message element - #onInvalid(event: any) { + #onInvalid(event: Event) { event.stopPropagation(); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-upload-field/preview/input-upload-field-file.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-upload-field/preview/input-upload-field-file.element.ts index 6f7412d1a1..6dd332e83b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-upload-field/preview/input-upload-field-file.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-upload-field/preview/input-upload-field-file.element.ts @@ -1,11 +1,15 @@ +import { html, customElement, property, state, css, when } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app'; import type { PropertyValueMap } from '@umbraco-cms/backoffice/external/lit'; -import { html, customElement, property, state, css } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @customElement('umb-input-upload-field-file') export default class UmbInputUploadFieldFileElement extends UmbLitElement { - @property({ type: String }) + #loadingText = `(${this.localize.term('general_loading')}...)`; + + #serverUrl = ''; + + @property() path: string = ''; /** @@ -22,53 +26,39 @@ export default class UmbInputUploadFieldFileElement extends UmbLitElement { @state() label = ''; - #serverUrl = ''; - - #loadingText = `(${this.localize.term('general_loading')}...)`; - - /** - * - */ constructor() { super(); + this.consumeContext(UMB_APP_CONTEXT, (instance) => { this.#serverUrl = instance.getServerUrl(); - }).asPromise(); + }); } protected override updated(_changedProperties: PropertyValueMap | Map): void { super.updated(_changedProperties); + if (_changedProperties.has('file') && this.file) { this.extension = this.file.name.split('.').pop() ?? ''; this.label = this.file.name || this.#loadingText; } - if (_changedProperties.has('path')) { - if (this.#serverUrl) { - if (this.file) return; - - this.extension = this.path.split('.').pop() ?? ''; - this.label = this.#serverUrl ? this.path.substring(this.#serverUrl.length) : this.#loadingText; - } + if (_changedProperties.has('path') && !this.file) { + this.extension = this.path.split('.').pop() ?? ''; + this.label = this.path.split('/').pop() ?? this.#loadingText; } } - #renderLabel() { - if (this.path) { - // Don't make it a link if it's a temp file upload. - return this.file ? this.label : html`${this.label}`; - } - - return html`${this.label}`; - } - override render() { if (!this.label && !this.extension) return html``; return html`
- ${this.#renderLabel()} + ${when( + !this.file && this.path, + () => html`${this.label}`, + () => html`${this.label}`, + )}
`; } @@ -81,26 +71,30 @@ export default class UmbInputUploadFieldFileElement extends UmbLitElement { box-sizing: border-box; color: var(--uui-color-text); } + #file-symbol { aspect-ratio: 1 / 1; margin: auto; max-width: 100%; max-height: 100%; } + #label { text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--uui-color-text); - } - a#label { - text-decoration: none; - color: var(--uui-color-interactive); - } - a#label:hover { - text-decoration: underline; - color: var(--uui-color-interactive-emphasis); + + &:is(a) { + text-decoration: none; + color: var(--uui-color-interactive); + + &:hover { + text-decoration: underline; + color: var(--uui-color-interactive-emphasis); + } + } } `, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/upload-field/Umbraco.UploadField.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/upload-field/Umbraco.UploadField.ts index fe697d8989..ba74e968d8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/upload-field/Umbraco.UploadField.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/property-editors/upload-field/Umbraco.UploadField.ts @@ -11,7 +11,7 @@ export const manifest: ManifestPropertyEditorSchema = { { alias: 'fileExtensions', label: 'Accepted file extensions', - propertyEditorUiAlias: 'Umb.PropertyEditorUi.MultipleTextString', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.AcceptedUploadTypes', }, ], }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/index.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/index.ts new file mode 100644 index 0000000000..0d1a4e6250 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/index.ts @@ -0,0 +1 @@ +export * from './property-editor-ui-accepted-upload-types.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/manifests.ts new file mode 100644 index 0000000000..a88774c861 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/manifests.ts @@ -0,0 +1,15 @@ +import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/property-editor'; + +export const manifest: ManifestPropertyEditorUi = { + type: 'propertyEditorUi', + alias: 'Umb.PropertyEditorUi.AcceptedUploadTypes', + name: 'Accepted Upload Types Property Editor UI', + element: () => import('./property-editor-ui-accepted-upload-types.element.js'), + meta: { + label: 'Accepted Upload Types', + propertyEditorSchemaAlias: 'Umbraco.MultipleTextstring', + icon: 'icon-ordered-list', + group: 'lists', + supportsReadOnly: true, + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/property-editor-ui-accepted-upload-types.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/property-editor-ui-accepted-upload-types.element.ts new file mode 100644 index 0000000000..9a85fa2b83 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/property-editor-ui-accepted-upload-types.element.ts @@ -0,0 +1,143 @@ +import { UmbPropertyEditorUIMultipleTextStringElement } from '../multiple-text-string/property-editor-ui-multiple-text-string.element.js'; +import { css, customElement, html, nothing, state, when } from '@umbraco-cms/backoffice/external/lit'; +import { formatBytes } from '@umbraco-cms/backoffice/utils'; +import { UmbTemporaryFileConfigRepository } from '@umbraco-cms/backoffice/temporary-file'; +import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/property-editor'; +import type { UmbTemporaryFileConfigurationModel } from '@umbraco-cms/backoffice/temporary-file'; + +/** + * @element umb-property-editor-ui-accepted-upload-types + */ +@customElement('umb-property-editor-ui-accepted-upload-types') +export class UmbPropertyEditorUIAcceptedUploadTypesElement + extends UmbPropertyEditorUIMultipleTextStringElement + implements UmbPropertyEditorUiElement +{ + #temporaryFileConfigRepository = new UmbTemporaryFileConfigRepository(this); + + @state() + protected _acceptedTypes: string[] = []; + + @state() + protected _disallowedTypes: string[] = []; + + @state() + protected _maxFileSize?: number | null; + + override async connectedCallback() { + super.connectedCallback(); + + await this.#temporaryFileConfigRepository.initialized; + this.observe(this.#temporaryFileConfigRepository.all(), (config) => { + if (!config) return; + + this.#addValidators(config); + + this._acceptedTypes = config.allowedUploadedFileExtensions; + this._disallowedTypes = config.disallowedUploadedFilesExtensions; + this._maxFileSize = config.maxFileSize ? config.maxFileSize * 1024 : null; + }); + } + + #addValidators(config: UmbTemporaryFileConfigurationModel) { + this._inputElement?.addValidator( + 'badInput', + () => { + let message = this.localize.term('validation_invalidExtensions'); + if (config.allowedUploadedFileExtensions.length) { + message += `
${this.localize.term('validation_allowedExtensions')} ${config.allowedUploadedFileExtensions.join(', ')}`; + } + if (config.disallowedUploadedFilesExtensions.length) { + message += `
${this.localize.term('validation_disallowedExtensions')} ${config.disallowedUploadedFilesExtensions.join(', ')}`; + } + return message; + }, + () => { + const extensions = this._inputElement?.items; + if (!extensions) return false; + if ( + config.allowedUploadedFileExtensions.length && + !config.allowedUploadedFileExtensions.some((ext) => extensions.includes(ext)) + ) { + return true; + } + if (config.disallowedUploadedFilesExtensions.some((ext) => extensions.includes(ext))) { + return true; + } + return false; + }, + ); + } + + #renderAcceptedTypes() { + if (!this._acceptedTypes.length && !this._disallowedTypes.length && !this._maxFileSize) { + return nothing; + } + + return html` + +

+ ${when( + this._acceptedTypes.length, + () => html` +

+ + ${this._acceptedTypes.join(', ')} +

+ `, + )} + ${when( + this._disallowedTypes.length, + () => html` +

+ + ${this._disallowedTypes.join(', ')} +

+ `, + )} + ${when( + this._maxFileSize, + () => html` +

+ ${this.localize.term('media_maxFileSize')} + ${formatBytes(this._maxFileSize!, { decimals: 2 })}. +

+ `, + )} +
+ `; + } + + override render() { + return html`${this.#renderAcceptedTypes()} ${super.render()}`; + } + + static override readonly styles = [ + css` + #notice { + --uui-box-default-padding: var(--uui-size-space-4); + --uui-box-header-padding: var(--uui-size-space-4); + --uui-color-divider-standalone: var(--uui-color-warning-standalone); + + border: 1px solid var(--uui-color-divider-standalone); + background-color: var(--uui-color-warning); + color: var(--uui-color-warning-contrast); + margin-bottom: var(--uui-size-layout-1); + + p { + margin: 0.5rem 0; + } + } + `, + ]; +} + +export default UmbPropertyEditorUIAcceptedUploadTypesElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-property-editor-ui-accepted-upload-types': UmbPropertyEditorUIAcceptedUploadTypesElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/property-editor-ui-accepted-upload-types.stories.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/property-editor-ui-accepted-upload-types.stories.ts new file mode 100644 index 0000000000..b2803dff05 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/property-editor-ui-accepted-upload-types.stories.ts @@ -0,0 +1,15 @@ +import type { UmbPropertyEditorUIAcceptedUploadTypesElement } from './property-editor-ui-accepted-upload-types.element.js'; +import type { Meta, StoryFn } from '@storybook/web-components'; +import { html } from '@umbraco-cms/backoffice/external/lit'; + +import './property-editor-ui-accepted-types.element.js'; + +export default { + title: 'Property Editor UIs/Accepted Types', + component: 'umb-property-editor-ui-accepted-types', + id: 'umb-property-editor-ui-accepted-types', +} as Meta; + +export const AAAOverview: StoryFn = () => + html``; +AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/property-editor-ui-accepted-upload-types.test.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/property-editor-ui-accepted-upload-types.test.ts new file mode 100644 index 0000000000..89d065a7ca --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/accepted-types/property-editor-ui-accepted-upload-types.test.ts @@ -0,0 +1,23 @@ +import { UmbPropertyEditorUIAcceptedUploadTypesElement } from './property-editor-ui-accepted-upload-types.element.js'; +import { expect, fixture, html } from '@open-wc/testing'; +import { type UmbTestRunnerWindow, defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; + +describe('UmbPropertyEditorUIUploadFieldElement', () => { + let element: UmbPropertyEditorUIAcceptedUploadTypesElement; + + beforeEach(async () => { + element = await fixture(html` + + `); + }); + + it('is defined with its own instance', () => { + expect(element).to.be.instanceOf(UmbPropertyEditorUIAcceptedUploadTypesElement); + }); + + if ((window as UmbTestRunnerWindow).__UMBRACO_TEST_RUN_A11Y_TEST) { + it('passes the a11y audit', async () => { + await expect(element).shadowDom.to.be.accessible(defaultA11yConfig); + }); + } +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/manifests.ts index 55595ce291..4ded362fc7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/manifests.ts @@ -1,3 +1,4 @@ +import { manifest as acceptedType } from './accepted-types/manifests.js'; import { manifest as colorEditor } from './color-swatches-editor/manifests.js'; import { manifest as numberRange } from './number-range/manifests.js'; import { manifest as orderDirection } from './order-direction/manifests.js'; @@ -38,6 +39,7 @@ export const manifests: Array = [ ...textBoxManifests, ...toggleManifests, ...contentPickerManifests, + acceptedType, colorEditor, numberRange, orderDirection, diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/multiple-text-string/property-editor-ui-multiple-text-string.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/multiple-text-string/property-editor-ui-multiple-text-string.element.ts index 8cbeee6b93..269630d09c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/multiple-text-string/property-editor-ui-multiple-text-string.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/multiple-text-string/property-editor-ui-multiple-text-string.element.ts @@ -1,13 +1,18 @@ -import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; -import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { customElement, html, property, query, state } from '@umbraco-cms/backoffice/external/lit'; +import { umbBindToValidation, UmbValidationContext } from '@umbraco-cms/backoffice/validation'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; +import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property'; +import { + UMB_SUBMITTABLE_WORKSPACE_CONTEXT, + UmbSubmittableWorkspaceContextBase, +} from '@umbraco-cms/backoffice/workspace'; import type { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import type { UmbInputMultipleTextStringElement } from '@umbraco-cms/backoffice/components'; import type { UmbPropertyEditorConfigCollection, UmbPropertyEditorUiElement, } from '@umbraco-cms/backoffice/property-editor'; -import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property'; /** * @element umb-property-editor-ui-multiple-text-string @@ -60,11 +65,23 @@ export class UmbPropertyEditorUIMultipleTextStringElement extends UmbLitElement @state() private _max = Infinity; + @query('#input', true) + protected _inputElement?: UmbInputMultipleTextStringElement; + + protected _validationContext = new UmbValidationContext(this); + constructor() { super(); + this.consumeContext(UMB_PROPERTY_CONTEXT, (context) => { this._label = context.getLabel(); }); + + this.consumeContext(UMB_SUBMITTABLE_WORKSPACE_CONTEXT, (context) => { + if (context instanceof UmbSubmittableWorkspaceContextBase) { + context.addValidationContext(this._validationContext); + } + }); } protected override firstUpdated() { @@ -83,17 +100,31 @@ export class UmbPropertyEditorUIMultipleTextStringElement extends UmbLitElement this.dispatchEvent(new UmbPropertyValueChangeEvent()); } + // Prevent valid events from bubbling outside the message element + #onValid(event: Event) { + event.stopPropagation(); + } + + // Prevent invalid events from bubbling outside the message element + #onInvalid(event: Event) { + event.stopPropagation(); + } + override render() { return html` - - + + + + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts index 11fa8c6391..ee3c9d5a5a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/manifests.ts @@ -16,27 +16,43 @@ export const manifests: Array = [ properties: [ { alias: 'default', - label: 'Initial State', - description: - 'The initial state for the toggle, when it is displayed for the first time in the backoffice, eg. for a new content item.', + label: 'Preset value', propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle', + config: [ + + { + alias: "ariaLabel", + value: 'toggle for the initial state of this data type' + } + ] }, { alias: 'showLabels', - label: 'Show toggle labels', - description: 'Show labels next to toggle button.', + label: 'Show on/off labels', propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle', + config: [ + + { + alias: "ariaLabel", + value: 'toggle for weather if label should be displayed' + } + ] }, { alias: 'labelOn', label: 'Label On', - description: 'Label text when enabled.', + description: 'Displays text when enabled.', propertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox', }, { alias: 'labelOff', label: 'Label Off', - description: 'Label text when disabled.', + description: 'Displays text when disabled.', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox', + }, + { + alias: 'ariaLabel', + label: 'Screen Reader Label', propertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox', }, ], diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts index 903e0b4694..a48dd0a130 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts @@ -24,21 +24,30 @@ export class UmbPropertyEditorUIToggleElement extends UmbLitElement implements U @property({ type: Boolean, reflect: true }) readonly = false; + @state() + _ariaLabel?: string; + @state() _labelOff?: string; @state() _labelOn?: string; + @property({ type: String }) + name?: string; + @state() _showLabels = false; + public set config(config: UmbPropertyEditorConfigCollection | undefined) { if (!config) return; this.value ??= config.getValueByAlias('default') ?? false; + this._labelOff = config.getValueByAlias('labelOff'); this._labelOn = config.getValueByAlias('labelOn'); this._showLabels = Boolean(config.getValueByAlias('showLabels')); + this._ariaLabel = config.getValueByAlias('ariaLabel'); } #onChange(event: CustomEvent & { target: UmbInputToggleElement }) { @@ -49,7 +58,8 @@ export class UmbPropertyEditorUIToggleElement extends UmbLitElement implements U override render() { return html`