Merge pull request #922 from umbraco/feature/markdown-editor-actions
Markdown Edtior Actions
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
import { UmbCodeEditorElement, loadCodeEditor } from '@umbraco-cms/backoffice/code-editor';
|
||||
import { css, html, customElement, query, property } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { KeyCode, KeyMod } from 'monaco-editor';
|
||||
import { UmbCodeEditorController, UmbCodeEditorElement, loadCodeEditor } from '@umbraco-cms/backoffice/code-editor';
|
||||
import { css, html, customElement, query, property, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { FormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import {
|
||||
UMB_LINK_PICKER_MODAL,
|
||||
UMB_MEDIA_TREE_PICKER_MODAL,
|
||||
UMB_MODAL_MANAGER_CONTEXT_TOKEN,
|
||||
UmbModalManagerContext,
|
||||
} from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
/**
|
||||
* @element umb-input-markdown
|
||||
@@ -12,40 +19,514 @@ import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
@customElement('umb-input-markdown')
|
||||
export class UmbInputMarkdownElement extends FormControlMixin(UmbLitElement) {
|
||||
protected getFormElement() {
|
||||
return undefined;
|
||||
return this._codeEditor;
|
||||
}
|
||||
|
||||
@property({ type: Boolean })
|
||||
preview?: boolean;
|
||||
|
||||
#isCodeEditorReady = new UmbBooleanState(false);
|
||||
isCodeEditorReady = this.#isCodeEditorReady.asObservable();
|
||||
#editor?: UmbCodeEditorController;
|
||||
|
||||
@query('umb-code-editor')
|
||||
_codeEditor?: UmbCodeEditorElement;
|
||||
|
||||
private _modalContext?: UmbModalManagerContext;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#loadCodeEditor();
|
||||
this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => {
|
||||
this._modalContext = instance;
|
||||
});
|
||||
}
|
||||
|
||||
async #loadCodeEditor() {
|
||||
try {
|
||||
await loadCodeEditor();
|
||||
this._codeEditor?.editor?.updateOptions({
|
||||
this.#isCodeEditorReady.next(true);
|
||||
|
||||
this.#editor = this._codeEditor?.editor;
|
||||
|
||||
this.#editor?.updateOptions({
|
||||
lineNumbers: false,
|
||||
minimap: false,
|
||||
folding: false,
|
||||
});
|
||||
this.#isCodeEditorReady.next(true);
|
||||
this.#loadActions();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async #loadActions() {
|
||||
// TODO: Find a way to have "double" keybindings (ctrl+m+ctrl+c for `code`, rather than simple ctrl+c as its taken by OS to copy things)
|
||||
// Going with the keybindings of a Markdown Shortcut plugin https://marketplace.visualstudio.com/items?itemName=robole.markdown-shortcuts#shortcuts or perhaps there are keybindings that would make more sense.
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Heading H1',
|
||||
id: 'h1',
|
||||
keybindings: [KeyMod.CtrlCmd | KeyCode.Digit1],
|
||||
run: () => this._insertAtCurrentLine('#'),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Heading H2',
|
||||
id: 'h2',
|
||||
keybindings: [KeyMod.CtrlCmd | KeyCode.Digit2],
|
||||
run: () => this._insertAtCurrentLine('##'),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Heading H3',
|
||||
id: 'h3',
|
||||
keybindings: [KeyMod.CtrlCmd | KeyCode.Digit3],
|
||||
run: () => this._insertAtCurrentLine('###'),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Heading H4',
|
||||
id: 'h4',
|
||||
keybindings: [KeyMod.CtrlCmd | KeyCode.Digit4],
|
||||
run: () => this._insertAtCurrentLine('####'),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Heading H5',
|
||||
id: 'h5',
|
||||
keybindings: [KeyMod.CtrlCmd | KeyCode.Digit5],
|
||||
run: () => this._insertAtCurrentLine('#####'),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Heading H6',
|
||||
id: 'h6',
|
||||
keybindings: [KeyMod.CtrlCmd | KeyCode.Digit6],
|
||||
run: () => this._insertAtCurrentLine('######'),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Bold Text',
|
||||
id: 'b',
|
||||
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyB],
|
||||
run: () => this._insertBetweenSelection('**', '**', 'Your Bold Text'),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Italic Text',
|
||||
id: 'i',
|
||||
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyI],
|
||||
run: () => this._insertBetweenSelection('*', '*', 'Your Italic Text'),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Quote',
|
||||
id: 'q',
|
||||
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyQ],
|
||||
run: () => this._insertQuote(),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Ordered List',
|
||||
id: 'ol',
|
||||
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyO],
|
||||
run: () => this._insertAtCurrentLine('1. '),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Unordered List',
|
||||
id: 'ul',
|
||||
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyU],
|
||||
run: () => this._insertAtCurrentLine('- '),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Code',
|
||||
id: 'code',
|
||||
//keybindings: [KeyMod.CtrlCmd | KeyCode.KeyM | KeyMod.CtrlCmd | KeyCode.KeyC],
|
||||
run: () => this._insertBetweenSelection('`', '`', 'Code'),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Fenced Code',
|
||||
id: 'fenced-code',
|
||||
//keybindings: [KeyMod.CtrlCmd | KeyCode.KeyM | KeyMod.CtrlCmd | KeyCode.KeyF],
|
||||
run: () => this._insertBetweenSelection('```', '```', 'Code'),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Line',
|
||||
id: 'line',
|
||||
//keybindings: [KeyMod.CtrlCmd | KeyCode.KeyM | KeyMod.CtrlCmd | KeyCode.KeyC],
|
||||
run: () => this._insertLine(),
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Link',
|
||||
id: 'link',
|
||||
//keybindings: [KeyMod.CtrlCmd | KeyCode.KeyM | KeyMod.CtrlCmd | KeyCode.KeyC],
|
||||
run: () => this._insertLink(),
|
||||
// TODO: Open in modal
|
||||
});
|
||||
this.#editor?.monacoEditor?.addAction({
|
||||
label: 'Add Image',
|
||||
id: 'image',
|
||||
//keybindings: [KeyMod.CtrlCmd | KeyCode.KeyM | KeyMod.CtrlCmd | KeyCode.KeyC],
|
||||
run: () => this._insertMedia(),
|
||||
// TODO: Open in modal
|
||||
});
|
||||
}
|
||||
|
||||
private _focusEditor(): void {
|
||||
// If we press one of the action buttons manually (which is outside the editor), we need to focus the editor again.
|
||||
this.#editor?.monacoEditor?.focus();
|
||||
}
|
||||
|
||||
private _insertLink() {
|
||||
const selection = this.#editor?.getSelections()[0];
|
||||
if (!selection) return;
|
||||
|
||||
const selectedValue = this.#editor?.getValueInRange(selection);
|
||||
|
||||
this._focusEditor(); // Focus before opening modal
|
||||
const modalContext = this._modalContext?.open(UMB_LINK_PICKER_MODAL, {
|
||||
index: null,
|
||||
link: { name: selectedValue },
|
||||
config: {},
|
||||
});
|
||||
|
||||
modalContext
|
||||
?.onSubmit()
|
||||
.then((data) => {
|
||||
const name = this.localize.term('general_name');
|
||||
const url = this.localize.term('general_url');
|
||||
|
||||
this.#editor?.monacoEditor?.executeEdits('', [
|
||||
{ range: selection, text: `[${data.link.name || name}](${data.link.url || url})` },
|
||||
]);
|
||||
|
||||
if (!data.link.name) {
|
||||
this.#editor?.select({
|
||||
startColumn: selection.startColumn + 1,
|
||||
endColumn: selection.startColumn + 1 + name.length,
|
||||
endLineNumber: selection.startLineNumber,
|
||||
startLineNumber: selection.startLineNumber,
|
||||
});
|
||||
} else if (!data.link.url) {
|
||||
this.#editor?.select({
|
||||
startColumn: selection.startColumn + 3 + data.link.name.length,
|
||||
endColumn: selection.startColumn + 3 + data.link.name.length + url.length,
|
||||
endLineNumber: selection.startLineNumber,
|
||||
startLineNumber: selection.startLineNumber,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => undefined)
|
||||
.finally(() => this._focusEditor());
|
||||
}
|
||||
|
||||
private _insertMedia() {
|
||||
const selection = this.#editor?.getSelections()[0];
|
||||
if (!selection) return;
|
||||
|
||||
const alt = this.#editor?.getValueInRange(selection);
|
||||
|
||||
this._focusEditor(); // Focus before opening modal
|
||||
const modalContext = this._modalContext?.open(UMB_MEDIA_TREE_PICKER_MODAL, {});
|
||||
|
||||
modalContext
|
||||
?.onSubmit()
|
||||
.then((data) => {
|
||||
const imgUrl = data.selection[0];
|
||||
this.#editor?.monacoEditor?.executeEdits('', [
|
||||
//TODO: media url
|
||||
{ range: selection, text: `[${alt || 'alt text'}](TODO: id-${imgUrl || this.localize.term('general_url')})` },
|
||||
]);
|
||||
|
||||
if (!alt?.length) {
|
||||
this.#editor?.select({
|
||||
startColumn: selection.startColumn + 1,
|
||||
endColumn: selection.startColumn + 9,
|
||||
endLineNumber: selection.startLineNumber,
|
||||
startLineNumber: selection.startLineNumber,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => undefined)
|
||||
.finally(() => this._focusEditor());
|
||||
}
|
||||
|
||||
private _insertLine() {
|
||||
const selection = this.#editor?.getSelections()[0];
|
||||
if (!selection) return;
|
||||
|
||||
const endColumn = this.#editor?.monacoModel?.getLineMaxColumn(selection.endLineNumber) ?? 1;
|
||||
|
||||
if (endColumn === 1) {
|
||||
this.#editor?.insertAtPosition('---\n', {
|
||||
lineNumber: selection.endLineNumber,
|
||||
column: 1,
|
||||
});
|
||||
} else {
|
||||
this.#editor?.insertAtPosition('\n---\n', {
|
||||
lineNumber: selection.endLineNumber,
|
||||
column: endColumn,
|
||||
});
|
||||
}
|
||||
this._focusEditor();
|
||||
}
|
||||
|
||||
private _insertBetweenSelection(startValue: string, endValue: string, placeholder?: string) {
|
||||
this._focusEditor();
|
||||
const selection = this.#editor?.getSelections()[0];
|
||||
if (!selection) return;
|
||||
|
||||
const selectedValue = this.#editor?.getValueInRange({
|
||||
startLineNumber: selection.startLineNumber,
|
||||
endLineNumber: selection.endLineNumber,
|
||||
startColumn: selection.startColumn - startValue.length,
|
||||
endColumn: selection.endColumn + endValue.length,
|
||||
});
|
||||
|
||||
if (
|
||||
selectedValue?.startsWith(startValue) &&
|
||||
selectedValue.endsWith(endValue) &&
|
||||
selectedValue.length > startValue.length + endValue.length
|
||||
) {
|
||||
//Cancel previous insert
|
||||
this.#editor?.select({ ...selection, startColumn: selection.startColumn + startValue.length });
|
||||
this.#editor?.monacoEditor?.executeEdits('', [
|
||||
{
|
||||
range: {
|
||||
startColumn: selection.startColumn - startValue.length,
|
||||
startLineNumber: selection.startLineNumber,
|
||||
endColumn: selection.startColumn,
|
||||
endLineNumber: selection.startLineNumber,
|
||||
},
|
||||
text: '',
|
||||
},
|
||||
{
|
||||
range: {
|
||||
startColumn: selection.endColumn + startValue.length,
|
||||
startLineNumber: selection.startLineNumber,
|
||||
endColumn: selection.endColumn,
|
||||
endLineNumber: selection.startLineNumber,
|
||||
},
|
||||
text: '',
|
||||
},
|
||||
]);
|
||||
} else {
|
||||
// Insert
|
||||
this.#editor?.insertAtPosition(startValue, {
|
||||
lineNumber: selection.startLineNumber,
|
||||
column: selection.startColumn,
|
||||
});
|
||||
this.#editor?.insertAtPosition(endValue, {
|
||||
lineNumber: selection.endLineNumber,
|
||||
column: selection.endColumn + startValue.length,
|
||||
});
|
||||
|
||||
this.#editor?.select({
|
||||
startLineNumber: selection.startLineNumber,
|
||||
endLineNumber: selection.endLineNumber,
|
||||
startColumn: selection.startColumn + startValue.length,
|
||||
endColumn: selection.endColumn + startValue.length,
|
||||
});
|
||||
}
|
||||
|
||||
// if no text were selected when action fired
|
||||
if (selection.startColumn === selection.endColumn && selection.startLineNumber === selection.endLineNumber) {
|
||||
if (placeholder) {
|
||||
this.#editor?.insertAtPosition(placeholder, {
|
||||
lineNumber: selection.startLineNumber,
|
||||
column: selection.startColumn + startValue.length,
|
||||
});
|
||||
}
|
||||
|
||||
this.#editor?.select({
|
||||
startLineNumber: selection.startLineNumber,
|
||||
endLineNumber: selection.endLineNumber,
|
||||
startColumn: selection.startColumn + startValue.length,
|
||||
endColumn: selection.startColumn + startValue.length + (placeholder?.length ?? 0),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _insertAtCurrentLine(value: string) {
|
||||
this._focusEditor();
|
||||
const selection = this.#editor?.getSelections()[0];
|
||||
if (!selection) return;
|
||||
|
||||
const previousLineValue = this.#editor?.getValueInRange({
|
||||
...selection,
|
||||
startLineNumber: selection.startLineNumber - 1,
|
||||
});
|
||||
const lineValue = this.#editor?.getValueInRange({ ...selection, startColumn: 1 });
|
||||
|
||||
// Regex: check if the line starts with a positive number followed by dot and a space
|
||||
if (lineValue?.startsWith(value) || lineValue?.match(/^[1-9]\d*\.\s.*/)) {
|
||||
// Cancel previous insert
|
||||
this.#editor?.monacoEditor?.executeEdits('', [
|
||||
{
|
||||
range: {
|
||||
startColumn: 1,
|
||||
startLineNumber: selection.startLineNumber,
|
||||
endColumn: 1 + value.length,
|
||||
endLineNumber: selection.startLineNumber,
|
||||
},
|
||||
text: '',
|
||||
},
|
||||
]);
|
||||
} else if (value.match(/^[1-9]\d*\.\s.*/) && previousLineValue?.match(/^[1-9]\d*\.\s.*/)) {
|
||||
// Check if the PREVIOUS line starts with a positive number followed by dot and a space. If yes, get that number.
|
||||
const previousNumber = parseInt(previousLineValue, 10);
|
||||
this.#editor?.insertAtPosition(`${previousNumber + 1}. `, {
|
||||
lineNumber: selection.startLineNumber,
|
||||
column: 1,
|
||||
});
|
||||
} else {
|
||||
// Insert
|
||||
this.#editor?.insertAtPosition(value, {
|
||||
lineNumber: selection.startLineNumber,
|
||||
column: 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _insertQuote() {
|
||||
const selection = this.#editor?.getSelections()[0];
|
||||
if (!selection) return;
|
||||
|
||||
let index = selection.startLineNumber;
|
||||
for (index; index <= selection.endLineNumber; index++) {
|
||||
const line = this.#editor?.getValueInRange({
|
||||
startLineNumber: index,
|
||||
endLineNumber: index,
|
||||
startColumn: 1,
|
||||
endColumn: 3,
|
||||
});
|
||||
if (!line?.startsWith('> ')) {
|
||||
this.#editor?.insertAtPosition('> ', {
|
||||
lineNumber: index,
|
||||
column: 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
this._focusEditor();
|
||||
}
|
||||
|
||||
private _renderBasicActions() {
|
||||
return html`<div>
|
||||
<uui-button
|
||||
compact
|
||||
look="secondary"
|
||||
label="Heading"
|
||||
title="Heading"
|
||||
@click=${() => this.#editor?.monacoEditor?.getAction('h1')?.run()}>
|
||||
H
|
||||
</uui-button>
|
||||
<uui-button
|
||||
compact
|
||||
look="secondary"
|
||||
label="Bold"
|
||||
title="Bold"
|
||||
@click=${() => this.#editor?.monacoEditor?.getAction('b')?.run()}>
|
||||
B
|
||||
</uui-button>
|
||||
<uui-button
|
||||
compact
|
||||
look="secondary"
|
||||
label="Italic"
|
||||
title="Italic"
|
||||
@click=${() => this.#editor?.monacoEditor?.getAction('i')?.run()}>
|
||||
I
|
||||
</uui-button>
|
||||
</div>
|
||||
<div>
|
||||
<uui-button
|
||||
compact
|
||||
look="secondary"
|
||||
label="Quote"
|
||||
title="Quote"
|
||||
@click=${() => this.#editor?.monacoEditor?.getAction('q')?.run()}>
|
||||
<uui-icon name="umb:quote"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-button
|
||||
compact
|
||||
look="secondary"
|
||||
label="Ordered List"
|
||||
title="Ordered List"
|
||||
@click=${() => this.#editor?.monacoEditor?.getAction('ol')?.run()}>
|
||||
<uui-icon name="umb:ordered-list"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-button
|
||||
compact
|
||||
look="secondary"
|
||||
label="Unordered List"
|
||||
title="Unordered List"
|
||||
@click=${() => this.#editor?.monacoEditor?.getAction('ul')?.run()}>
|
||||
<uui-icon name="umb:bulleted-list"></uui-icon>
|
||||
</uui-button>
|
||||
</div>
|
||||
<div>
|
||||
<uui-button
|
||||
compact
|
||||
look="secondary"
|
||||
label="Fenced Code"
|
||||
title="Fenced Code"
|
||||
@click=${() => this.#editor?.monacoEditor?.getAction('fenced-code')?.run()}>
|
||||
<uui-icon name="umb:code"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-button
|
||||
compact
|
||||
look="secondary"
|
||||
label="Line"
|
||||
title="Line"
|
||||
@click=${() => this.#editor?.monacoEditor?.getAction('line')?.run()}>
|
||||
<uui-icon name="umb:width"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-button
|
||||
compact
|
||||
look="secondary"
|
||||
label="Link"
|
||||
title="Link"
|
||||
@click=${() => this.#editor?.monacoEditor?.getAction('link')?.run()}>
|
||||
<uui-icon name="umb:link"></uui-icon>
|
||||
</uui-button>
|
||||
<uui-button
|
||||
compact
|
||||
look="secondary"
|
||||
label="Image"
|
||||
title="Image"
|
||||
@click=${() => this.#editor?.monacoEditor?.getAction('image')?.run()}>
|
||||
<uui-icon name="umb:picture"></uui-icon>
|
||||
</uui-button>
|
||||
</div>
|
||||
<div>
|
||||
<uui-button
|
||||
compact
|
||||
label="Press F1 for all actions"
|
||||
title="Press F1 for all actions"
|
||||
@click=${() => {
|
||||
this._focusEditor();
|
||||
this.#editor?.monacoEditor?.trigger('', 'editor.action.quickCommand', '');
|
||||
}}>
|
||||
<uui-key>F1</uui-key>
|
||||
</uui-button>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
onKeyPress(e: KeyboardEvent) {
|
||||
if (e.key !== 'Enter') return;
|
||||
//TODO: Tab does not seem to trigger keyboard events. We need to make some logic for ordered and unordered lists when tab is being used.
|
||||
|
||||
const selection = this.#editor?.getSelections()[0];
|
||||
if (!selection) return;
|
||||
|
||||
const lineValue = this.#editor?.getValueInRange({ ...selection, startColumn: 1 }).trimStart();
|
||||
if (!lineValue) return;
|
||||
|
||||
if (lineValue.startsWith('- ') && lineValue.length > 2) {
|
||||
requestAnimationFrame(() => this.#editor?.insert('- '));
|
||||
} else if (lineValue.match(/^[1-9]\d*\.\s.*/) && lineValue.length > 3) {
|
||||
const previousNumber = parseInt(lineValue, 10);
|
||||
requestAnimationFrame(() => this.#editor?.insert(`${previousNumber + 1}. `));
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` <div id="actions"></div>
|
||||
<umb-code-editor language="markdown" .code=${this.value as string}></umb-code-editor>
|
||||
//TODO: Why is the theme dark in Backoffice, but light in Storybook?
|
||||
return html` <div id="actions">${this._renderBasicActions()}</div>
|
||||
<umb-code-editor
|
||||
language="markdown"
|
||||
.code=${this.value as string}
|
||||
@keypress=${this.onKeyPress}
|
||||
theme="umb-light"></umb-code-editor>
|
||||
${this.renderPreview()}`;
|
||||
}
|
||||
|
||||
@@ -63,6 +544,16 @@ export class UmbInputMarkdownElement extends FormControlMixin(UmbLitElement) {
|
||||
#actions {
|
||||
background-color: var(--uui-color-background-alt);
|
||||
display: flex;
|
||||
gap: var(--uui-size-6);
|
||||
}
|
||||
|
||||
#actions div {
|
||||
display: flex;
|
||||
gap: var(--uui-size-1);
|
||||
}
|
||||
|
||||
#actions div:last-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
umb-code-editor {
|
||||
@@ -70,6 +561,10 @@ export class UmbInputMarkdownElement extends FormControlMixin(UmbLitElement) {
|
||||
border-radius: var(--uui-border-radius);
|
||||
border: 1px solid var(--uui-color-divider-emphasis);
|
||||
}
|
||||
|
||||
uui-button {
|
||||
width: 50px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -153,6 +153,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
|
||||
return html`<uui-label for="search-input">Link to page</uui-label>
|
||||
<uui-input id="search-input" placeholder="Type to search" label="Type to search"></uui-input>
|
||||
<umb-tree
|
||||
?multiple=${false}
|
||||
alias="Umb.Tree.Documents"
|
||||
@selected=${(event: CustomEvent) => this._handleSelectionChange(event, 'document')}
|
||||
.selection=${[this._selectedKey ?? '']}
|
||||
@@ -163,6 +164,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
|
||||
<uui-label>Link to media</uui-label>
|
||||
|
||||
<umb-tree
|
||||
?multiple=${false}
|
||||
alias="Umb.Tree.Media"
|
||||
@selected=${(event: CustomEvent) => this._handleSelectionChange(event, 'media')}
|
||||
.selection=${[this._selectedKey ?? '']}
|
||||
|
||||
Reference in New Issue
Block a user