diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-upload-field/input-upload-field.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-upload-field/input-upload-field.element.ts index 6dce37947f..96110d38c2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-upload-field/input-upload-field.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-upload-field/input-upload-field.element.ts @@ -172,6 +172,9 @@ export class UmbInputUploadFieldElement extends UmbLitElement { static styles = [ css` + :host { + position: relative; + } uui-icon { vertical-align: sub; margin-right: var(--uui-size-space-4); diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts index d8e8f2d220..b5434aefe9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/views/grid/media-grid-collection-view.element.ts @@ -116,7 +116,6 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement { } #renderItem(item: UmbMediaCollectionItemModel) { - // TODO: Fix the file extension when media items have a file extension. [?] return html` this.#onOpen(event, item.unique)} @selected=${() => this.#onSelect(item)} @deselected=${() => this.#onDeselect(item)} - class="media-item" - file-ext="${item.icon}"> + class="media-item"> ${item.url ? html`${item.name}` : html``} @@ -156,7 +154,7 @@ export class UmbMediaGridCollectionViewElement extends UmbLitElement { gap: var(--uui-size-space-5); } umb-icon { - font-size: var(--uui-size-24); + font-size: var(--uui-size-8); } `, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper-focus-setter.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper-focus-setter.element.ts index e23da648b4..ce4783482f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper-focus-setter.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper-focus-setter.element.ts @@ -5,20 +5,15 @@ import { LitElement, css, html, nothing, customElement, property, query } from ' @customElement('umb-image-cropper-focus-setter') export class UmbImageCropperFocusSetterElement extends LitElement { - @query('#image') imageElement?: HTMLImageElement; + @query('#image') imageElement!: HTMLImageElement; @query('#wrapper') wrapperElement?: HTMLImageElement; - @query('#focal-point') focalPointElement?: HTMLImageElement; + @query('#focal-point') focalPointElement!: HTMLImageElement; @property({ type: String }) src?: string; @property({ attribute: false }) focalPoint: UmbImageCropperFocalPoint = { left: 0.5, top: 0.5 }; #DOT_RADIUS = 6 as const; - connectedCallback() { - super.connectedCallback(); - this.#addEventListeners(); - } - disconnectedCallback() { super.disconnectedCallback(); this.#removeEventListeners(); @@ -33,33 +28,46 @@ export class UmbImageCropperFocusSetterElement extends LitElement { } } + protected update(changedProperties: PropertyValueMap | Map): void { + super.update(changedProperties); + + if (changedProperties.has('src')) { + if (this.src) { + this.#initializeImage(); + } + } + } + protected firstUpdated(_changedProperties: PropertyValueMap | Map): void { super.firstUpdated(_changedProperties); this.style.setProperty('--dot-radius', `${this.#DOT_RADIUS}px`); + } - if (this.focalPointElement) { - this.focalPointElement.style.left = `calc(${this.focalPoint.left * 100}% - ${this.#DOT_RADIUS}px)`; - this.focalPointElement.style.top = `calc(${this.focalPoint.top * 100}% - ${this.#DOT_RADIUS}px)`; - } - if (this.imageElement) { - this.imageElement.onload = () => { - if (!this.imageElement || !this.wrapperElement) return; - const imageAspectRatio = this.imageElement.naturalWidth / this.imageElement.naturalHeight; - const hostRect = this.getBoundingClientRect(); - const image = this.imageElement.getBoundingClientRect(); + async #initializeImage() { + await this.updateComplete; // Wait for the @query to be resolved - if (image.width > hostRect.width) { - this.imageElement.style.width = '100%'; - } - if (image.height > hostRect.height) { - this.imageElement.style.height = '100%'; - } + this.focalPointElement.style.left = `calc(${this.focalPoint.left * 100}% - ${this.#DOT_RADIUS}px)`; + this.focalPointElement.style.top = `calc(${this.focalPoint.top * 100}% - ${this.#DOT_RADIUS}px)`; - this.imageElement.style.aspectRatio = `${imageAspectRatio}`; - this.wrapperElement.style.aspectRatio = `${imageAspectRatio}`; - }; - } + this.imageElement.onload = () => { + if (!this.imageElement || !this.wrapperElement) return; + const imageAspectRatio = this.imageElement.naturalWidth / this.imageElement.naturalHeight; + const hostRect = this.getBoundingClientRect(); + const image = this.imageElement.getBoundingClientRect(); + + if (image.width > hostRect.width) { + this.imageElement.style.width = '100%'; + } + if (image.height > hostRect.height) { + this.imageElement.style.height = '100%'; + } + + this.imageElement.style.aspectRatio = `${imageAspectRatio}`; + this.wrapperElement.style.aspectRatio = `${imageAspectRatio}`; + }; + + this.#addEventListeners(); } async #addEventListeners() { @@ -134,6 +142,7 @@ export class UmbImageCropperFocusSetterElement extends LitElement { } /* Wrapper is used to make the focal point position responsive to the image size */ #wrapper { + overflow: hidden; position: relative; display: flex; margin: auto; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper-preview.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper-preview.element.ts index ffda92c71c..7d94c9740e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper-preview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper-preview.element.ts @@ -33,11 +33,7 @@ export class UmbImageCropperPreviewElement extends LitElement { if (!this.crop) return; await this.updateComplete; // Wait for the @query to be resolved - - if (!this.imageElement.complete) { - // Wait for the image to load - await new Promise((resolve) => (this.imageElement.onload = () => resolve(this.imageElement))); - } + await new Promise((resolve) => (this.imageElement.onload = () => resolve(this.imageElement))); const container = this.imageContainerElement.getBoundingClientRect(); const cropAspectRatio = this.crop.width / this.crop.height; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper.element.ts index 6599c9a769..807193942c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-image-cropper/image-cropper.element.ts @@ -376,6 +376,7 @@ export class UmbImageCropperElement extends LitElement { #image { display: block; position: absolute; + user-select: none; } #slider { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.element.ts index bba1bda31e..70e3e0c948 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media/input-media.element.ts @@ -199,7 +199,6 @@ export class UmbInputMediaElement extends UUIFormControlMixin(UmbLitElement, '') } #renderItem(item: UmbMediaCardItemModel) { - // TODO: `file-ext` value has been hardcoded here. Find out if API model has value for it. [LK] return html` ${item.url @@ -208,10 +207,11 @@ export class UmbInputMediaElement extends UUIFormControlMixin(UmbLitElement, '') ${this.#renderIsTrashed(item)} ${this.#renderOpenButton(item)} - + this.#pickerContext.requestRemoveItem(item.unique)} label="Remove media ${item.name}"> @@ -264,6 +264,10 @@ export class UmbInputMediaElement extends UUIFormControlMixin(UmbLitElement, '') margin: 0 auto; } + uui-card-media umb-icon { + font-size: var(--uui-size-8); + } + uui-card-media[drag-placeholder] { opacity: 0.2; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/dropzone/dropzone.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/dropzone/dropzone.element.ts index f3f4e8b4ca..726347040b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/dropzone/dropzone.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/dropzone/dropzone.element.ts @@ -16,6 +16,9 @@ export class UmbDropzoneElement extends UmbLitElement { @property({ type: Boolean }) createAsTemporary: boolean = false; + @property({ type: Array, attribute: false }) + accept: Array = []; + //TODO: logic to disable the dropzone? #files: Array = []; @@ -92,10 +95,10 @@ export class UmbDropzoneElement extends UmbLitElement { render() { return html``; + label="${this.localize.term('media_dragAndDropYourFilesIntoTheArea')}">`; } static styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/media-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/media-picker-modal.element.ts index a3aa80888b..de83d120a3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/media-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/modals/media-picker/media-picker-modal.element.ts @@ -247,7 +247,7 @@ export class UmbMediaPickerModalElement extends UmbModalBaseElement