import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import { css, customElement, html, ifDefined, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UMB_CONFIRM_MODAL, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
import { UMB_NOTIFICATION_CONTEXT, type UmbNotificationDefaultData } from '@umbraco-cms/backoffice/notification';
import type {
UmbPropertyEditorConfigCollection,
UmbPropertyEditorUiElement,
} from '@umbraco-cms/backoffice/property-editor';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation';
@customElement('my-suggestions-property-editor-ui')
export default class MySuggestionsPropertyEditorUIElement
extends UmbFormControlMixin<string | undefined, typeof UmbLitElement, undefined>(UmbLitElement, undefined)
implements UmbPropertyEditorUiElement {
@property({ type: String })
public override set value(value: string | undefined) {
super.value = value;
}
public override get value(): string | undefined {
return super.value;
}
@state()
private _disabled?: boolean;
@state()
private _placeholder?: string;
@state()
private _maxChars?: number;
@state()
private _suggestions = [
'You should take a break',
'I suggest that you visit the Eiffel Tower',
'How about starting a book club today or this week?',
'Are you hungry?',
];
@property({ attribute: false })
public set config(config: UmbPropertyEditorConfigCollection) {
this._disabled = config.getValueByAlias('disabled');
this._placeholder = config.getValueByAlias('placeholder');
this._maxChars = config.getValueByAlias('maxChars');
}
#onInput(e: InputEvent) {
this.value = (e.target as HTMLInputElement).value;
this.#dispatchChangeEvent();
}
#onSuggestion() {
const randomIndex = (this._suggestions.length * Math.random()) | 0;
this.value = this._suggestions[randomIndex];
this.#dispatchChangeEvent();
}
#dispatchChangeEvent() {
this.dispatchEvent(new UmbChangeEvent());
}
#modalManagerContext?: typeof UMB_MODAL_MANAGER_CONTEXT.TYPE;
#notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE;
constructor() {
super();
this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (instance) => {
this.#modalManagerContext = instance;
});
this.consumeContext(UMB_NOTIFICATION_CONTEXT, (instance) => {
this.#notificationContext = instance;
});
this.addValidator(
'tooLong',
() => `Input must not exceed ${this._maxChars} characters`,
() => !!this._maxChars && (this.value?.length ?? 0) > this._maxChars,
);
}
protected override firstUpdated() {
this.addFormControlElement(this.shadowRoot!.querySelector('#suggestion-input')!);
}
#onTextTrim() {
if (!this._maxChars) return;
if (!this.value || this.value.length <= this._maxChars) {
const data: UmbNotificationDefaultData = {
message: `Nothing to trim!`,
};
this.#notificationContext?.peek('danger', { data });
return;
}
const trimmed = this.value.substring(0, this._maxChars);
const modalHandler = this.#modalManagerContext?.open(this, UMB_CONFIRM_MODAL, {
data: {
headline: `Trim text`,
content: `Do you want to trim the text to "${trimmed}"?`,
color: 'danger',
confirmLabel: 'Trim',
},
});
modalHandler?.onSubmit().then(() => {
this.value = trimmed;
this.#dispatchChangeEvent();
const data: UmbNotificationDefaultData = {
headline: `Text trimmed`,
message: `You trimmed the text!`,
};
this.#notificationContext?.peek('positive', { data });
}, null);
}
override render() {
return html`
<uui-input
id="suggestion-input"
class="element"
label="text input"
placeholder=${ifDefined(this._placeholder)}
maxlength=${ifDefined(this._maxChars)}
.value=${this.value ?? ''}
@input=${this.#onInput}>
</uui-input>
${this._maxChars !== undefined
? html`<p class="${(this.value?.length ?? 0) > this._maxChars ? 'over-limit' : ''}">
${this._maxChars - (this.value?.length ?? 0)} characters remaining
</p>`
: ''}
<div id="wrapper">
<uui-button
id="suggestion-button"
class="element"
look="primary"
label="give me suggestions"
?disabled=${this._disabled}
@click=${this.#onSuggestion}>
Give me suggestions!
</uui-button>
<uui-button id="suggestion-trimmer" class="element" look="outline" label="Trim text" @click=${this.#onTextTrim}>
Trim text
</uui-button>
</div>
`;
}
static override styles = [
UmbTextStyles,
css`
#wrapper {
margin-top: 10px;
display: flex;
gap: 10px;
}
.element {
width: 100%;
}
p {
font-size: 0.8em;
margin: 4px 0 0;
color: var(--uui-color-text-alt);
}
p.over-limit {
color: var(--uui-color-danger);
}
`,
];
}
declare global {
interface HTMLElementTagNameMap {
'my-suggestions-property-editor-ui': MySuggestionsPropertyEditorUIElement;
}
}