@api-client/ui 0.5.8 → 0.5.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -105,10 +105,19 @@ export default class MentionTextArea extends LitElement {
105
105
  private mentionMap;
106
106
  private mutationObserver?;
107
107
  private _value;
108
+ /**
109
+ * A read-only list of the names of the fields currently mentioned in the textarea.
110
+ */
111
+ get mentions(): string[];
108
112
  connectedCallback(): void;
109
113
  disconnectedCallback(): void;
110
114
  firstUpdated(): void;
111
115
  willUpdate(changedProperties: PropertyValues): void;
116
+ /**
117
+ * Get the plain text content without field references
118
+ * @returns The plain text content with field names instead of references
119
+ */
120
+ getPlainText(): string;
112
121
  /**
113
122
  * Sets the caret position at the beginning of a specific text node
114
123
  */
@@ -1 +1 @@
1
- {"version":3,"file":"MentionTextArea.d.ts","sourceRoot":"","sources":["../../../../../src/elements/mention-textarea/internals/MentionTextArea.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MentionTextArea.d.ts","sourceRoot":"","sources":["../../../../../src/elements/mention-textarea/internals/MentionTextArea.ts"],"names":[],"mappings":"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"}
@@ -254,6 +254,21 @@ let MentionTextArea = (() => {
254
254
  mentionMap = new Map();
255
255
  mutationObserver;
256
256
  _value = ''; // Internal value storage
257
+ /**
258
+ * A read-only list of the names of the fields currently mentioned in the textarea.
259
+ */
260
+ get mentions() {
261
+ const dependencies = new Set();
262
+ if (!this.value) {
263
+ return [];
264
+ }
265
+ const regex = /@\{([^}]+)\}/g;
266
+ let match;
267
+ while ((match = regex.exec(this.value)) !== null) {
268
+ dependencies.add(match[1]);
269
+ }
270
+ return Array.from(dependencies);
271
+ }
257
272
  connectedCallback() {
258
273
  super.connectedCallback();
259
274
  // Setup mutation observer to watch for changes in the editor
@@ -295,6 +310,19 @@ let MentionTextArea = (() => {
295
310
  }
296
311
  }
297
312
  }
313
+ /**
314
+ * Get the plain text content without field references
315
+ * @returns The plain text content with field names instead of references
316
+ */
317
+ getPlainText() {
318
+ let text = this.value;
319
+ // Replace field references with their display names
320
+ text = text.replace(/@\{([^}]+)\}/g, (match, fieldId) => {
321
+ const field = this.suggestions.find((f) => f.id === fieldId);
322
+ return field ? field.label : fieldId;
323
+ });
324
+ return text;
325
+ }
298
326
  /**
299
327
  * Sets the caret position at the beginning of a specific text node
300
328
  */
@@ -1 +1 @@
1
- {"version":3,"file":"MentionTextArea.js","sourceRoot":"","sources":["../../../../../src/elements/mention-textarea/internals/MentionTextArea.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, PropertyValues, TemplateResult, nothing } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport reactive from '../../../decorators/reactive.js'\nimport '../../../md/chip/ui-chip.js'\n\nexport interface MentionSuggestion {\n /** Unique identifier for the suggestion */\n id: string\n /** Main label/headline displayed */\n label: string\n /** Supporting description text */\n description?: string\n /** Suffix text (e.g., role, department) */\n suffix?: string\n /** Additional data associated with the suggestion */\n data?: Record<string, unknown>\n}\n\nexport interface MentionInsertEvent {\n /** The inserted mention suggestion */\n suggestion: MentionSuggestion\n /** The text that triggered the mention (e.g., \"@john\") */\n trigger: string\n /** The position where the mention was inserted */\n position: number\n}\n\nexport interface MentionRemoveEvent {\n /** The removed mention suggestion */\n suggestion: MentionSuggestion\n /** The position where the mention was removed from */\n position: number\n}\n\ninterface Fragment {\n type: 'text' | 'mention'\n content: string\n mentionId?: string\n}\n\n/**\n * A NodeFilter mask that includes text nodes and elements.\n * It is used with the NodeWalker\n */\nconst ShowMask = NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT\n\n/**\n * A material design textarea component that supports @mentions with suggestions.\n *\n * Features:\n * - Material Design styling\n * - @mention triggers with customizable suggestions\n * - Inline pill/chip rendering for mentions\n * - Proper caret management\n * - Keyboard navigation for suggestions\n * - Overflow container support\n * - Generic design for extensibility\n * - Accessibility support\n *\n * @fires mention-insert - When a mention is inserted\n * @fires mention-remove - When a mention is removed\n * @fires input - When the input value changes\n * @fires change - When the input loses focus and value has changed\n */\nexport default class MentionTextArea extends LitElement {\n /**\n * Shadow root configuration for the component.\n * Uses 'open' mode for accessibility and delegates focus to enable proper focus management.\n */\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n }\n\n /**\n * The label text displayed as placeholder/floating label\n */\n @property({ type: String })\n accessor label = ''\n\n /**\n * Supporting text displayed below the input\n */\n @property({ type: String, attribute: 'supporting-text' })\n accessor supportingText = ''\n\n /**\n * Whether the component is disabled\n */\n @property({ type: Boolean, reflect: true })\n accessor disabled = false\n\n /**\n * Whether the component is in an invalid state\n */\n @property({ type: Boolean, reflect: true })\n accessor invalid = false\n\n /**\n * The name attribute for form integration\n */\n @property({ type: String })\n accessor name = ''\n\n /**\n * Whether the input is required\n */\n @property({ type: Boolean })\n accessor required = false\n\n /**\n * Placeholder text shown when input is empty\n */\n @property({ type: String })\n accessor placeholder = ''\n\n get value(): string {\n return this._value\n }\n\n @property({ type: String })\n set value(newValue: string) {\n const oldValue = this._value\n if (newValue === this._value) return // No change, skip update\n this._value = newValue\n this.requestUpdate('value', oldValue)\n // Only sync editor from value when set externally and element is ready\n if (this.editorElement) {\n this.syncEditorFromValue()\n }\n }\n\n /**\n * Available suggestions for mentions\n */\n @property({ type: Array, attribute: false })\n accessor suggestions: MentionSuggestion[] = []\n\n /**\n * Character that triggers mention suggestions (default: '@')\n */\n @property({ type: String, attribute: 'mention-trigger' })\n accessor mentionTrigger = '@'\n\n /**\n * Minimum characters after trigger to show suggestions\n */\n @property({ type: Number, attribute: 'min-query-length' })\n accessor minQueryLength = 0\n\n @query('.editor')\n private accessor editorElement!: HTMLDivElement\n\n @query('.suggestions-popover')\n private accessor suggestionsPopover!: HTMLElement\n\n @state()\n @reactive()\n private accessor isShowingSuggestions = false\n\n @reactive()\n private accessor filteredSuggestions: MentionSuggestion[] = []\n\n @state()\n private accessor selectedSuggestionIndex = 0\n\n @state()\n private accessor hasContent = false\n\n @state()\n private accessor isLabelFloating = false\n\n @state()\n private accessor isEditorFocus = false\n\n private currentMentionQuery = ''\n private currentMentionStart = -1\n private mentionMap = new Map<string, MentionSuggestion>()\n private mutationObserver?: MutationObserver\n private _value = '' // Internal value storage\n\n override connectedCallback(): void {\n super.connectedCallback()\n\n // Setup mutation observer to watch for changes in the editor\n this.mutationObserver = new MutationObserver(() => {\n this.syncValueFromEditor()\n })\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback()\n this.mutationObserver?.disconnect()\n }\n\n override firstUpdated(): void {\n // Start observing mutations in the editor\n if (this.editorElement && this.mutationObserver) {\n this.mutationObserver.observe(this.editorElement, {\n childList: true,\n subtree: true,\n characterData: true,\n })\n }\n\n // Setup initial content\n this.updateComplete.then(() => {\n this.syncEditorFromValue()\n })\n }\n\n override willUpdate(changedProperties: PropertyValues): void {\n super.willUpdate(changedProperties)\n\n // No need to sync editor from value here since setter handles it\n\n if (changedProperties.has('suggestions')) {\n this.updateFilteredSuggestions()\n }\n if (changedProperties.has('selectedSuggestionIndex')) {\n const index = this.selectedSuggestionIndex\n if (index >= 0) {\n this.suggestionsPopover?.querySelector(`.suggestion-item:nth-child(${index + 1})`)?.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n })\n }\n }\n }\n\n /**\n * Sets the caret position at the beginning of a specific text node\n */\n private setCaretPositionAtTextNode(textNode: Text, offset = 0): void {\n const selection = window.getSelection()\n if (!selection) return\n\n const range = document.createRange()\n range.setStart(textNode, offset)\n range.setEnd(textNode, offset)\n\n selection.removeAllRanges()\n selection.addRange(range)\n }\n\n /**\n * Synchronizes the value property from the editor content\n */\n private syncValueFromEditor(): void {\n const newValue = this.getValueFromEditor()\n if (newValue !== this._value) {\n // Update internal value directly to avoid triggering setter\n this._value = newValue\n this.requestUpdate('value')\n this.dispatchEvent(new Event('input', { bubbles: true }))\n }\n\n this.updateContentState()\n }\n\n /**\n * Gets the value from editor content, converting chips to @{mention} format\n */\n private getValueFromEditor(): string {\n const childNodes = Array.from(this.editorElement.childNodes)\n let result = ''\n\n for (const node of childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n result += node.textContent || ''\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element\n if (element.classList.contains('mention-chip')) {\n const mentionId = element.getAttribute('data-mention-id')\n if (mentionId) {\n result += `@{${mentionId}}`\n }\n } else {\n result += element.textContent || ''\n }\n }\n }\n\n return result\n }\n\n /**\n * Synchronizes the editor content from the value property\n */\n private syncEditorFromValue(): void {\n if (!this.editorElement) return\n\n const fragments = this.parseValueToFragments(this._value)\n this.editorElement.innerHTML = ''\n\n for (const fragment of fragments) {\n if (fragment.type === 'text') {\n this.editorElement.appendChild(document.createTextNode(fragment.content))\n } else if (fragment.type === 'mention') {\n if (fragment.mentionId) {\n let mention = this.mentionMap.get(fragment.mentionId)\n\n // If mention not in map, try to find it in suggestions\n if (!mention) {\n mention = this.suggestions.find((s) => s.id === fragment.mentionId)\n if (mention) {\n // Add to map for future use\n this.mentionMap.set(mention.id, mention)\n }\n }\n\n if (mention) {\n const chipElement = this.createMentionChip(mention)\n this.editorElement.appendChild(chipElement)\n } else {\n // Fallback to text if mention not found anywhere\n this.editorElement.appendChild(document.createTextNode(`@{${fragment.mentionId}}`))\n }\n }\n }\n }\n\n this.updateContentState()\n }\n\n /**\n * Parses value string into text and mention fragments\n */\n private parseValueToFragments(value: string): Fragment[] {\n const fragments: Fragment[] = []\n const mentionRegex = /@\\{([^}]+)\\}/g\n let lastIndex = 0\n let match\n\n while ((match = mentionRegex.exec(value)) !== null) {\n // Add text before mention\n if (match.index > lastIndex) {\n fragments.push({\n type: 'text',\n content: value.substring(lastIndex, match.index),\n })\n }\n\n // Add mention\n fragments.push({\n type: 'mention',\n content: match[0],\n mentionId: match[1],\n })\n\n lastIndex = mentionRegex.lastIndex\n }\n\n // Add remaining text\n if (lastIndex < value.length) {\n fragments.push({\n type: 'text',\n content: value.substring(lastIndex),\n })\n }\n\n return fragments\n }\n\n /**\n * Creates a mention chip element\n */\n private createMentionChip(mention: MentionSuggestion): HTMLElement {\n const wrapper = document.createElement('span')\n wrapper.className = 'mention-chip'\n wrapper.setAttribute('data-mention-id', mention.id)\n wrapper.setAttribute('contenteditable', 'false')\n\n const chip = document.createElement('ui-chip')\n chip.setAttribute('type', 'input')\n chip.setAttribute('removable', 'true')\n chip.textContent = mention.label\n chip.addEventListener('remove', () => {\n this.removeMention(wrapper, mention)\n })\n\n wrapper.appendChild(chip)\n return wrapper\n }\n\n /**\n * Updates content state flags\n */\n private updateContentState(): void {\n const hasAnyContent =\n this.editorElement.childNodes.length > 0 && (this.editorElement.textContent?.trim().length || 0) > 0\n\n this.hasContent = hasAnyContent\n this.isLabelFloating = hasAnyContent || this.isShowingSuggestions || this.isEditorFocus\n }\n\n /**\n * Handles input events in the editor\n */\n private handleEditorInput(event: Event): void {\n event.stopPropagation()\n\n // Check for mention trigger\n this.checkForMentionTrigger()\n\n // Sync value\n this.syncValueFromEditor()\n }\n\n /**\n * Handles keydown events in the editor\n */\n private handleEditorKeyDown(event: KeyboardEvent): void {\n if (this.isShowingSuggestions) {\n this.handleSuggestionKeyDown(event)\n }\n }\n\n /**\n * Handles keydown events when suggestions are visible\n */\n private handleSuggestionKeyDown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowUp':\n event.preventDefault()\n this.selectedSuggestionIndex = Math.max(0, this.selectedSuggestionIndex - 1)\n break\n case 'ArrowDown':\n event.preventDefault()\n this.selectedSuggestionIndex = Math.min(this.filteredSuggestions.length - 1, this.selectedSuggestionIndex + 1)\n break\n case 'Enter':\n case 'Tab':\n event.preventDefault()\n this.selectSuggestion(this.filteredSuggestions[this.selectedSuggestionIndex])\n break\n case 'Escape':\n event.preventDefault()\n this.hideSuggestions()\n break\n }\n }\n\n /**\n * Handles focus events\n */\n private handleEditorFocus(): void {\n this.isEditorFocus = true\n this.updateContentState()\n }\n\n /**\n * Handles blur events\n */\n private handleEditorBlur(event: FocusEvent): void {\n // Don't hide suggestions if focus moved to suggestions popover\n if (event.relatedTarget && this.suggestionsPopover?.contains(event.relatedTarget as Node)) {\n return\n }\n\n this.isEditorFocus = false\n this.hideSuggestions()\n this.updateContentState()\n this.dispatchEvent(new Event('change', { bubbles: true }))\n }\n\n private handleEditorPaste(event: ClipboardEvent): void {\n // Prevent default paste behavior to handle mentions properly\n event.preventDefault()\n\n const pastedContent = event.clipboardData?.getData('text/plain')\n if (!pastedContent) return\n\n const selection = window.getSelection()\n if (!selection || selection.rangeCount === 0) return\n\n // Get the current range\n let range: Range | StaticRange\n if ('getComposedRanges' in selection && typeof selection.getComposedRanges === 'function' && this.shadowRoot) {\n const composedRanges = selection.getComposedRanges({ shadowRoots: [this.shadowRoot] })\n if (composedRanges.length === 0) return\n range = composedRanges[0]\n } else {\n range = selection.getRangeAt(0)\n }\n\n // Convert StaticRange to Range if needed for deleteContents\n let workingRange: Range\n if (range instanceof StaticRange) {\n workingRange = document.createRange()\n workingRange.setStart(range.startContainer, range.startOffset)\n workingRange.setEnd(range.endContainer, range.endOffset)\n } else {\n workingRange = range\n }\n\n // Delete the current selection (if any)\n workingRange.deleteContents()\n\n // Insert the pasted text at the current position\n const textNode = document.createTextNode(pastedContent)\n workingRange.insertNode(textNode)\n\n // Position cursor at the end of the inserted text\n workingRange.setStartAfter(textNode)\n workingRange.setEndAfter(textNode)\n selection.removeAllRanges()\n selection.addRange(workingRange)\n\n // Hide suggestions if showing\n this.hideSuggestions()\n\n // Sync value and trigger events\n this.syncValueFromEditor()\n }\n\n /**\n * Checks if the current caret position indicates a mention trigger\n */\n private checkForMentionTrigger(): void {\n const selection = window.getSelection()\n if (!selection || selection.rangeCount === 0) {\n this.hideSuggestions()\n return\n }\n\n // Use getComposedRanges() for shadow DOM support, fallback to getRangeAt()\n let range: Range | StaticRange\n if ('getComposedRanges' in selection && typeof selection.getComposedRanges === 'function' && this.shadowRoot) {\n const composedRanges = selection.getComposedRanges({ shadowRoots: [this.shadowRoot] })\n if (composedRanges.length === 0) {\n this.hideSuggestions()\n return\n }\n range = composedRanges[0]\n } else {\n range = selection.getRangeAt(0)\n }\n\n const caretContainer = range.startContainer\n const caretOffset = range.startOffset\n\n // Ensure the caret is within our editor element\n if (!this.editorElement.contains(caretContainer)) {\n this.hideSuggestions()\n return\n }\n\n // Only look for triggers in text nodes\n if (caretContainer.nodeType !== Node.TEXT_NODE) {\n this.hideSuggestions()\n return\n }\n\n const textContent = caretContainer.textContent || ''\n\n // Look backwards from caret to find mention trigger\n let mentionStart = -1\n for (let i = caretOffset - 1; i >= 0; i--) {\n const char = textContent[i]\n if (char === this.mentionTrigger) {\n mentionStart = i\n break\n }\n if (char === ' ' || char === '\\n') {\n break\n }\n }\n if (mentionStart >= 0) {\n const query = textContent.substring(mentionStart + 1, caretOffset)\n\n if (query.length >= this.minQueryLength) {\n this.currentMentionQuery = query\n this.currentMentionStart = this.getGlobalTextPosition(caretContainer, mentionStart)\n this.showSuggestions()\n this.updateFilteredSuggestions()\n } else {\n this.hideSuggestions()\n }\n } else {\n this.hideSuggestions()\n }\n }\n\n private walkerNodeFilter(node: Node): number {\n if (node.nodeType === Node.TEXT_NODE) {\n return NodeFilter.FILTER_ACCEPT\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element\n if (element.classList.contains('mention-chip')) {\n // Accept mention chips as single characters\n return NodeFilter.FILTER_ACCEPT\n } else if (element.parentElement?.classList.contains('mention-chip')) {\n // It's a chip, ignore the entire tree\n return NodeFilter.FILTER_REJECT\n }\n }\n return NodeFilter.FILTER_SKIP\n }\n\n /**\n * Gets the global text position within the editor for a position within a text node\n */\n private getGlobalTextPosition(textNode: Node, offsetInNode: number): number {\n let position = 0\n const walker = document.createTreeWalker(this.editorElement, ShowMask, this.walkerNodeFilter)\n\n let node = walker.nextNode()\n while (node && node !== textNode) {\n if (node.nodeType === Node.TEXT_NODE) {\n position += node.textContent?.length || 0\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element\n if (element.classList?.contains('mention-chip')) {\n position += 1 // Count chip as 1 character\n }\n }\n node = walker.nextNode()\n }\n\n return position + offsetInNode\n }\n\n /**\n * Finds the DOM node and offset that corresponds to a global text position\n */\n private findNodeAtGlobalPosition(globalPosition: number): { node: Node; offset: number } | null {\n let currentPosition = 0\n const walker = document.createTreeWalker(this.editorElement, ShowMask, this.walkerNodeFilter)\n\n let node = walker.nextNode()\n while (node) {\n if (node.nodeType === Node.TEXT_NODE) {\n const textLength = node.textContent?.length || 0\n if (currentPosition + textLength >= globalPosition) {\n return {\n node,\n offset: globalPosition - currentPosition,\n }\n }\n currentPosition += textLength\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element\n if (element.classList?.contains('mention-chip')) {\n if (currentPosition === globalPosition) {\n // Position is right before the chip\n const parentNode = element.parentNode\n if (parentNode) {\n return {\n node: parentNode,\n offset: Array.from(parentNode.childNodes).indexOf(element),\n }\n }\n }\n currentPosition += 1 // Count chip as 1 character\n }\n }\n node = walker.nextNode()\n }\n\n // Position is beyond the end, return the last position\n const lastChild = this.editorElement.lastChild\n if (lastChild) {\n if (lastChild.nodeType === Node.TEXT_NODE) {\n return {\n node: lastChild,\n offset: lastChild.textContent?.length || 0,\n }\n } else {\n return {\n node: this.editorElement,\n offset: this.editorElement.childNodes.length,\n }\n }\n }\n\n return null\n }\n\n /**\n * Shows the suggestions popover\n */\n private showSuggestions(): void {\n if (!this.isShowingSuggestions) {\n this.isShowingSuggestions = true\n this.selectedSuggestionIndex = 0\n this.updateContentState()\n\n // Use Popover API to show the popover\n this.updateComplete.then(() => {\n if (this.suggestionsPopover) {\n this.suggestionsPopover.showPopover()\n this.positionSuggestions()\n }\n })\n }\n }\n\n /**\n * Hides the suggestions popover\n */\n private hideSuggestions(): void {\n if (this.isShowingSuggestions) {\n this.isShowingSuggestions = false\n this.currentMentionQuery = ''\n this.currentMentionStart = -1\n this.updateContentState()\n\n // Use Popover API to hide the popover\n if (this.suggestionsPopover) {\n this.suggestionsPopover.hidePopover()\n }\n }\n }\n\n /**\n * Updates filtered suggestions based on current query\n */\n private updateFilteredSuggestions(): void {\n if (!this.currentMentionQuery) {\n this.filteredSuggestions = this.suggestions.slice(0, 10) // Limit to 10\n return\n }\n\n const query = this.currentMentionQuery.toLowerCase()\n this.filteredSuggestions = this.suggestions\n .filter(\n (suggestion) =>\n suggestion.label.toLowerCase().includes(query) ||\n suggestion.description?.toLowerCase().includes(query) ||\n suggestion.suffix?.toLowerCase().includes(query)\n )\n .slice(0, 10) // Limit to 10\n\n // Reset selection if needed\n if (this.selectedSuggestionIndex >= this.filteredSuggestions.length) {\n this.selectedSuggestionIndex = 0\n }\n }\n\n /**\n * Positions the suggestions popover using the Popover API anchor positioning\n */\n private positionSuggestions(): void {\n if (!this.suggestionsPopover) return\n\n const selection = window.getSelection()\n if (!selection || selection.rangeCount === 0) return\n\n // Use getComposedRanges() for shadow DOM support, fallback to getRangeAt()\n let range: Range | StaticRange\n if ('getComposedRanges' in selection && typeof selection.getComposedRanges === 'function' && this.shadowRoot) {\n const composedRanges = selection.getComposedRanges({ shadowRoots: [this.shadowRoot] })\n if (composedRanges.length === 0) return\n range = composedRanges[0]\n } else {\n range = selection.getRangeAt(0)\n }\n\n // Convert StaticRange to Range if needed for getBoundingClientRect\n let workingRange: Range\n if (range instanceof StaticRange) {\n workingRange = document.createRange()\n workingRange.setStart(range.startContainer, range.startOffset)\n workingRange.setEnd(range.endContainer, range.endOffset)\n } else {\n workingRange = range\n }\n\n const rect = workingRange.getBoundingClientRect()\n\n // Position suggestions below the caret using manual positioning as fallback\n // The Popover API will handle proper layering and overflow handling\n this.suggestionsPopover.style.left = `${rect.left}px`\n this.suggestionsPopover.style.top = `${rect.bottom + 4}px`\n }\n\n /**\n * Selects a suggestion and inserts it as a mention\n */\n private selectSuggestion(suggestion: MentionSuggestion): void {\n if (!suggestion) return\n\n // Add to mention map\n this.mentionMap.set(suggestion.id, suggestion)\n\n // Find the position where the mention trigger starts\n const mentionStart = this.currentMentionStart\n\n // Find the DOM node and offset for the mention start position\n const mentionStartInfo = this.findNodeAtGlobalPosition(mentionStart)\n\n if (!mentionStartInfo) {\n // Fallback: insert at the end\n const chip = this.createMentionChip(suggestion)\n const afterTextNode = document.createTextNode('')\n this.editorElement.appendChild(chip)\n this.editorElement.appendChild(afterTextNode)\n this.setCaretPositionAtTextNode(afterTextNode, 0)\n this.hideSuggestions()\n this.syncValueFromEditor()\n this.dispatchEvent(\n new CustomEvent<MentionInsertEvent>('mention-insert', {\n detail: {\n suggestion,\n trigger: this.mentionTrigger + this.currentMentionQuery,\n position: mentionStart,\n },\n bubbles: true,\n })\n )\n return\n }\n\n // If the target is not a text node, insert at the container level\n if (mentionStartInfo.node.nodeType !== Node.TEXT_NODE) {\n const chip = this.createMentionChip(suggestion)\n const container = mentionStartInfo.node\n const beforeNode = container.childNodes[mentionStartInfo.offset]\n\n // Create an empty text node for caret positioning\n const afterTextNode = document.createTextNode('')\n\n if (beforeNode) {\n container.insertBefore(chip, beforeNode)\n container.insertBefore(afterTextNode, beforeNode)\n } else {\n container.appendChild(chip)\n container.appendChild(afterTextNode)\n }\n\n // Position caret at the beginning of the after text node\n this.setCaretPositionAtTextNode(afterTextNode, 0)\n this.hideSuggestions()\n this.syncValueFromEditor()\n this.dispatchEvent(\n new CustomEvent<MentionInsertEvent>('mention-insert', {\n detail: {\n suggestion,\n trigger: this.mentionTrigger + this.currentMentionQuery,\n position: mentionStart,\n },\n bubbles: true,\n })\n )\n return\n }\n\n // We have a text node - split it and insert the chip\n const textNode = mentionStartInfo.node as Text\n const splitOffset = mentionStartInfo.offset\n\n // Create the mention chip\n const chip = this.createMentionChip(suggestion)\n\n // Split the text node at the mention start position\n const beforeText = textNode.textContent?.substring(0, splitOffset) || ''\n const afterText = textNode.textContent?.substring(splitOffset + 1) || '' // +1 to skip the trigger\n\n // Replace the original text node with the split content\n const parentNode = textNode.parentNode\n if (parentNode) {\n // Create new text nodes - always create afterTextNode even if empty\n const beforeTextNode = beforeText ? document.createTextNode(beforeText) : null\n const afterTextNode = document.createTextNode(afterText) // Always create, even if empty\n\n // Insert the nodes in order\n if (beforeTextNode) {\n parentNode.insertBefore(beforeTextNode, textNode)\n }\n parentNode.insertBefore(chip, textNode)\n parentNode.insertBefore(afterTextNode, textNode)\n\n // Remove the original text node\n parentNode.removeChild(textNode)\n\n // Position caret at the beginning of the after text node\n this.setCaretPositionAtTextNode(afterTextNode, 0)\n } else {\n // Fallback: append to editor and create a text node for caret positioning\n const afterTextNode = document.createTextNode('')\n this.editorElement.appendChild(chip)\n this.editorElement.appendChild(afterTextNode)\n this.setCaretPositionAtTextNode(afterTextNode, 0)\n }\n\n // Hide suggestions\n this.hideSuggestions()\n\n // Sync value and dispatch events\n this.syncValueFromEditor()\n this.dispatchEvent(\n new CustomEvent<MentionInsertEvent>('mention-insert', {\n detail: {\n suggestion,\n trigger: this.mentionTrigger + this.currentMentionQuery,\n position: mentionStart,\n },\n bubbles: true,\n })\n )\n }\n\n /**\n * Removes a mention chip\n */\n private removeMention(chipElement: HTMLElement, mention: MentionSuggestion): void {\n const position = this.getElementPosition(chipElement)\n chipElement.remove()\n\n this.syncValueFromEditor()\n this.dispatchEvent(\n new CustomEvent<MentionRemoveEvent>('mention-remove', {\n detail: {\n suggestion: mention,\n position,\n },\n bubbles: true,\n })\n )\n }\n\n /**\n * Gets the text position of an element\n */\n private getElementPosition(element: HTMLElement): number {\n let position = 0\n let currentNode = this.editorElement.firstChild\n\n while (currentNode && currentNode !== element) {\n if (currentNode.nodeType === Node.TEXT_NODE) {\n position += currentNode.textContent?.length || 0\n } else if (currentNode.nodeType === Node.ELEMENT_NODE) {\n const element = currentNode as Element\n if (element.classList?.contains('mention-chip')) {\n position += 1 // Count chip as 1 character\n }\n }\n currentNode = currentNode.nextSibling\n }\n\n return position\n }\n\n /**\n * Handles clicking on a suggestion\n */\n private handleSuggestionClick(suggestion: MentionSuggestion, event: Event): void {\n event.preventDefault()\n this.selectSuggestion(suggestion)\n this.focus()\n }\n\n /**\n * Renders a suggestion item\n */\n private renderSuggestion(suggestion: MentionSuggestion, index: number): TemplateResult {\n const isSelected = index === this.selectedSuggestionIndex\n const classes = classMap({\n 'suggestion-item': true,\n 'selected': isSelected,\n })\n\n return html`\n <button\n class=\"${classes}\"\n @click=\"${(e: Event) => this.handleSuggestionClick(suggestion, e)}\"\n @mouseenter=\"${() => (this.selectedSuggestionIndex = index)}\"\n >\n <div class=\"suggestion-content\">\n <div class=\"suggestion-headline\">${suggestion.label}</div>\n ${suggestion.description\n ? html` <div class=\"suggestion-supporting-text\">${suggestion.description}</div> `\n : nothing}\n </div>\n ${suggestion.suffix ? html` <div class=\"suggestion-suffix\">${suggestion.suffix}</div> ` : nothing}\n </button>\n `\n }\n\n /**\n * Renders the suggestions popover\n */\n private renderSuggestions(): TemplateResult {\n return html`\n <div class=\"suggestions-popover\" popover=\"manual\">\n ${this.isShowingSuggestions && this.filteredSuggestions.length > 0\n ? this.filteredSuggestions.map((suggestion, index) => this.renderSuggestion(suggestion, index))\n : nothing}\n </div>\n `\n }\n\n override render(): TemplateResult {\n const surfaceClasses = classMap({\n 'surface': true,\n 'has-content': this.hasContent,\n })\n\n const labelClasses = classMap({\n label: true,\n floating: this.isLabelFloating,\n })\n\n return html`\n <div class=\"${surfaceClasses}\">\n <div class=\"container\"></div>\n <div class=\"content\">\n <div class=\"body\">\n ${this.label ? html`<div class=\"${labelClasses}\">${this.label}</div>` : nothing}\n <div\n class=\"editor\"\n contenteditable=\"${!this.disabled}\"\n data-placeholder=\"${ifDefined(this.placeholder)}\"\n @input=\"${this.handleEditorInput}\"\n @keydown=\"${this.handleEditorKeyDown}\"\n @focus=\"${this.handleEditorFocus}\"\n @blur=\"${this.handleEditorBlur}\"\n @paste=\"${this.handleEditorPaste}\"\n role=\"textbox\"\n aria-label=\"${ifDefined(this.label)}\"\n aria-multiline=\"true\"\n aria-required=\"${this.required}\"\n aria-invalid=\"${this.invalid}\"\n tabindex=\"${this.disabled ? -1 : 0}\"\n ></div>\n </div>\n </div>\n ${this.renderSuggestions()}\n </div>\n ${this.supportingText ? html` <div class=\"supporting-text\">${this.supportingText}</div> ` : nothing}\n `\n }\n}\n"]}
1
+ {"version":3,"file":"MentionTextArea.js","sourceRoot":"","sources":["../../../../../src/elements/mention-textarea/internals/MentionTextArea.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, PropertyValues, TemplateResult, nothing } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\nimport { classMap } from 'lit/directives/class-map.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\nimport reactive from '../../../decorators/reactive.js'\nimport '../../../md/chip/ui-chip.js'\n\nexport interface MentionSuggestion {\n /** Unique identifier for the suggestion */\n id: string\n /** Main label/headline displayed */\n label: string\n /** Supporting description text */\n description?: string\n /** Suffix text (e.g., role, department) */\n suffix?: string\n /** Additional data associated with the suggestion */\n data?: Record<string, unknown>\n}\n\nexport interface MentionInsertEvent {\n /** The inserted mention suggestion */\n suggestion: MentionSuggestion\n /** The text that triggered the mention (e.g., \"@john\") */\n trigger: string\n /** The position where the mention was inserted */\n position: number\n}\n\nexport interface MentionRemoveEvent {\n /** The removed mention suggestion */\n suggestion: MentionSuggestion\n /** The position where the mention was removed from */\n position: number\n}\n\ninterface Fragment {\n type: 'text' | 'mention'\n content: string\n mentionId?: string\n}\n\n/**\n * A NodeFilter mask that includes text nodes and elements.\n * It is used with the NodeWalker\n */\nconst ShowMask = NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT\n\n/**\n * A material design textarea component that supports @mentions with suggestions.\n *\n * Features:\n * - Material Design styling\n * - @mention triggers with customizable suggestions\n * - Inline pill/chip rendering for mentions\n * - Proper caret management\n * - Keyboard navigation for suggestions\n * - Overflow container support\n * - Generic design for extensibility\n * - Accessibility support\n *\n * @fires mention-insert - When a mention is inserted\n * @fires mention-remove - When a mention is removed\n * @fires input - When the input value changes\n * @fires change - When the input loses focus and value has changed\n */\nexport default class MentionTextArea extends LitElement {\n /**\n * Shadow root configuration for the component.\n * Uses 'open' mode for accessibility and delegates focus to enable proper focus management.\n */\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n }\n\n /**\n * The label text displayed as placeholder/floating label\n */\n @property({ type: String })\n accessor label = ''\n\n /**\n * Supporting text displayed below the input\n */\n @property({ type: String, attribute: 'supporting-text' })\n accessor supportingText = ''\n\n /**\n * Whether the component is disabled\n */\n @property({ type: Boolean, reflect: true })\n accessor disabled = false\n\n /**\n * Whether the component is in an invalid state\n */\n @property({ type: Boolean, reflect: true })\n accessor invalid = false\n\n /**\n * The name attribute for form integration\n */\n @property({ type: String })\n accessor name = ''\n\n /**\n * Whether the input is required\n */\n @property({ type: Boolean })\n accessor required = false\n\n /**\n * Placeholder text shown when input is empty\n */\n @property({ type: String })\n accessor placeholder = ''\n\n get value(): string {\n return this._value\n }\n\n @property({ type: String })\n set value(newValue: string) {\n const oldValue = this._value\n if (newValue === this._value) return // No change, skip update\n this._value = newValue\n this.requestUpdate('value', oldValue)\n // Only sync editor from value when set externally and element is ready\n if (this.editorElement) {\n this.syncEditorFromValue()\n }\n }\n\n /**\n * Available suggestions for mentions\n */\n @property({ type: Array, attribute: false })\n accessor suggestions: MentionSuggestion[] = []\n\n /**\n * Character that triggers mention suggestions (default: '@')\n */\n @property({ type: String, attribute: 'mention-trigger' })\n accessor mentionTrigger = '@'\n\n /**\n * Minimum characters after trigger to show suggestions\n */\n @property({ type: Number, attribute: 'min-query-length' })\n accessor minQueryLength = 0\n\n @query('.editor')\n private accessor editorElement!: HTMLDivElement\n\n @query('.suggestions-popover')\n private accessor suggestionsPopover!: HTMLElement\n\n @state()\n @reactive()\n private accessor isShowingSuggestions = false\n\n @reactive()\n private accessor filteredSuggestions: MentionSuggestion[] = []\n\n @state()\n private accessor selectedSuggestionIndex = 0\n\n @state()\n private accessor hasContent = false\n\n @state()\n private accessor isLabelFloating = false\n\n @state()\n private accessor isEditorFocus = false\n\n private currentMentionQuery = ''\n private currentMentionStart = -1\n private mentionMap = new Map<string, MentionSuggestion>()\n private mutationObserver?: MutationObserver\n private _value = '' // Internal value storage\n\n /**\n * A read-only list of the names of the fields currently mentioned in the textarea.\n */\n get mentions(): string[] {\n const dependencies = new Set<string>()\n if (!this.value) {\n return []\n }\n const regex = /@\\{([^}]+)\\}/g\n let match: RegExpExecArray | null\n while ((match = regex.exec(this.value)) !== null) {\n dependencies.add(match[1])\n }\n return Array.from(dependencies)\n }\n\n override connectedCallback(): void {\n super.connectedCallback()\n\n // Setup mutation observer to watch for changes in the editor\n this.mutationObserver = new MutationObserver(() => {\n this.syncValueFromEditor()\n })\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback()\n this.mutationObserver?.disconnect()\n }\n\n override firstUpdated(): void {\n // Start observing mutations in the editor\n if (this.editorElement && this.mutationObserver) {\n this.mutationObserver.observe(this.editorElement, {\n childList: true,\n subtree: true,\n characterData: true,\n })\n }\n\n // Setup initial content\n this.updateComplete.then(() => {\n this.syncEditorFromValue()\n })\n }\n\n override willUpdate(changedProperties: PropertyValues): void {\n super.willUpdate(changedProperties)\n\n // No need to sync editor from value here since setter handles it\n\n if (changedProperties.has('suggestions')) {\n this.updateFilteredSuggestions()\n }\n if (changedProperties.has('selectedSuggestionIndex')) {\n const index = this.selectedSuggestionIndex\n if (index >= 0) {\n this.suggestionsPopover?.querySelector(`.suggestion-item:nth-child(${index + 1})`)?.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n })\n }\n }\n }\n\n /**\n * Get the plain text content without field references\n * @returns The plain text content with field names instead of references\n */\n public getPlainText(): string {\n let text = this.value\n\n // Replace field references with their display names\n text = text.replace(/@\\{([^}]+)\\}/g, (match, fieldId) => {\n const field = this.suggestions.find((f) => f.id === fieldId)\n return field ? field.label : fieldId\n })\n\n return text\n }\n\n /**\n * Sets the caret position at the beginning of a specific text node\n */\n private setCaretPositionAtTextNode(textNode: Text, offset = 0): void {\n const selection = window.getSelection()\n if (!selection) return\n\n const range = document.createRange()\n range.setStart(textNode, offset)\n range.setEnd(textNode, offset)\n\n selection.removeAllRanges()\n selection.addRange(range)\n }\n\n /**\n * Synchronizes the value property from the editor content\n */\n private syncValueFromEditor(): void {\n const newValue = this.getValueFromEditor()\n if (newValue !== this._value) {\n // Update internal value directly to avoid triggering setter\n this._value = newValue\n this.requestUpdate('value')\n this.dispatchEvent(new Event('input', { bubbles: true }))\n }\n\n this.updateContentState()\n }\n\n /**\n * Gets the value from editor content, converting chips to @{mention} format\n */\n private getValueFromEditor(): string {\n const childNodes = Array.from(this.editorElement.childNodes)\n let result = ''\n\n for (const node of childNodes) {\n if (node.nodeType === Node.TEXT_NODE) {\n result += node.textContent || ''\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element\n if (element.classList.contains('mention-chip')) {\n const mentionId = element.getAttribute('data-mention-id')\n if (mentionId) {\n result += `@{${mentionId}}`\n }\n } else {\n result += element.textContent || ''\n }\n }\n }\n\n return result\n }\n\n /**\n * Synchronizes the editor content from the value property\n */\n private syncEditorFromValue(): void {\n if (!this.editorElement) return\n\n const fragments = this.parseValueToFragments(this._value)\n this.editorElement.innerHTML = ''\n\n for (const fragment of fragments) {\n if (fragment.type === 'text') {\n this.editorElement.appendChild(document.createTextNode(fragment.content))\n } else if (fragment.type === 'mention') {\n if (fragment.mentionId) {\n let mention = this.mentionMap.get(fragment.mentionId)\n\n // If mention not in map, try to find it in suggestions\n if (!mention) {\n mention = this.suggestions.find((s) => s.id === fragment.mentionId)\n if (mention) {\n // Add to map for future use\n this.mentionMap.set(mention.id, mention)\n }\n }\n\n if (mention) {\n const chipElement = this.createMentionChip(mention)\n this.editorElement.appendChild(chipElement)\n } else {\n // Fallback to text if mention not found anywhere\n this.editorElement.appendChild(document.createTextNode(`@{${fragment.mentionId}}`))\n }\n }\n }\n }\n\n this.updateContentState()\n }\n\n /**\n * Parses value string into text and mention fragments\n */\n private parseValueToFragments(value: string): Fragment[] {\n const fragments: Fragment[] = []\n const mentionRegex = /@\\{([^}]+)\\}/g\n let lastIndex = 0\n let match\n\n while ((match = mentionRegex.exec(value)) !== null) {\n // Add text before mention\n if (match.index > lastIndex) {\n fragments.push({\n type: 'text',\n content: value.substring(lastIndex, match.index),\n })\n }\n\n // Add mention\n fragments.push({\n type: 'mention',\n content: match[0],\n mentionId: match[1],\n })\n\n lastIndex = mentionRegex.lastIndex\n }\n\n // Add remaining text\n if (lastIndex < value.length) {\n fragments.push({\n type: 'text',\n content: value.substring(lastIndex),\n })\n }\n\n return fragments\n }\n\n /**\n * Creates a mention chip element\n */\n private createMentionChip(mention: MentionSuggestion): HTMLElement {\n const wrapper = document.createElement('span')\n wrapper.className = 'mention-chip'\n wrapper.setAttribute('data-mention-id', mention.id)\n wrapper.setAttribute('contenteditable', 'false')\n\n const chip = document.createElement('ui-chip')\n chip.setAttribute('type', 'input')\n chip.setAttribute('removable', 'true')\n chip.textContent = mention.label\n chip.addEventListener('remove', () => {\n this.removeMention(wrapper, mention)\n })\n\n wrapper.appendChild(chip)\n return wrapper\n }\n\n /**\n * Updates content state flags\n */\n private updateContentState(): void {\n const hasAnyContent =\n this.editorElement.childNodes.length > 0 && (this.editorElement.textContent?.trim().length || 0) > 0\n\n this.hasContent = hasAnyContent\n this.isLabelFloating = hasAnyContent || this.isShowingSuggestions || this.isEditorFocus\n }\n\n /**\n * Handles input events in the editor\n */\n private handleEditorInput(event: Event): void {\n event.stopPropagation()\n\n // Check for mention trigger\n this.checkForMentionTrigger()\n\n // Sync value\n this.syncValueFromEditor()\n }\n\n /**\n * Handles keydown events in the editor\n */\n private handleEditorKeyDown(event: KeyboardEvent): void {\n if (this.isShowingSuggestions) {\n this.handleSuggestionKeyDown(event)\n }\n }\n\n /**\n * Handles keydown events when suggestions are visible\n */\n private handleSuggestionKeyDown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'ArrowUp':\n event.preventDefault()\n this.selectedSuggestionIndex = Math.max(0, this.selectedSuggestionIndex - 1)\n break\n case 'ArrowDown':\n event.preventDefault()\n this.selectedSuggestionIndex = Math.min(this.filteredSuggestions.length - 1, this.selectedSuggestionIndex + 1)\n break\n case 'Enter':\n case 'Tab':\n event.preventDefault()\n this.selectSuggestion(this.filteredSuggestions[this.selectedSuggestionIndex])\n break\n case 'Escape':\n event.preventDefault()\n this.hideSuggestions()\n break\n }\n }\n\n /**\n * Handles focus events\n */\n private handleEditorFocus(): void {\n this.isEditorFocus = true\n this.updateContentState()\n }\n\n /**\n * Handles blur events\n */\n private handleEditorBlur(event: FocusEvent): void {\n // Don't hide suggestions if focus moved to suggestions popover\n if (event.relatedTarget && this.suggestionsPopover?.contains(event.relatedTarget as Node)) {\n return\n }\n\n this.isEditorFocus = false\n this.hideSuggestions()\n this.updateContentState()\n this.dispatchEvent(new Event('change', { bubbles: true }))\n }\n\n private handleEditorPaste(event: ClipboardEvent): void {\n // Prevent default paste behavior to handle mentions properly\n event.preventDefault()\n\n const pastedContent = event.clipboardData?.getData('text/plain')\n if (!pastedContent) return\n\n const selection = window.getSelection()\n if (!selection || selection.rangeCount === 0) return\n\n // Get the current range\n let range: Range | StaticRange\n if ('getComposedRanges' in selection && typeof selection.getComposedRanges === 'function' && this.shadowRoot) {\n const composedRanges = selection.getComposedRanges({ shadowRoots: [this.shadowRoot] })\n if (composedRanges.length === 0) return\n range = composedRanges[0]\n } else {\n range = selection.getRangeAt(0)\n }\n\n // Convert StaticRange to Range if needed for deleteContents\n let workingRange: Range\n if (range instanceof StaticRange) {\n workingRange = document.createRange()\n workingRange.setStart(range.startContainer, range.startOffset)\n workingRange.setEnd(range.endContainer, range.endOffset)\n } else {\n workingRange = range\n }\n\n // Delete the current selection (if any)\n workingRange.deleteContents()\n\n // Insert the pasted text at the current position\n const textNode = document.createTextNode(pastedContent)\n workingRange.insertNode(textNode)\n\n // Position cursor at the end of the inserted text\n workingRange.setStartAfter(textNode)\n workingRange.setEndAfter(textNode)\n selection.removeAllRanges()\n selection.addRange(workingRange)\n\n // Hide suggestions if showing\n this.hideSuggestions()\n\n // Sync value and trigger events\n this.syncValueFromEditor()\n }\n\n /**\n * Checks if the current caret position indicates a mention trigger\n */\n private checkForMentionTrigger(): void {\n const selection = window.getSelection()\n if (!selection || selection.rangeCount === 0) {\n this.hideSuggestions()\n return\n }\n\n // Use getComposedRanges() for shadow DOM support, fallback to getRangeAt()\n let range: Range | StaticRange\n if ('getComposedRanges' in selection && typeof selection.getComposedRanges === 'function' && this.shadowRoot) {\n const composedRanges = selection.getComposedRanges({ shadowRoots: [this.shadowRoot] })\n if (composedRanges.length === 0) {\n this.hideSuggestions()\n return\n }\n range = composedRanges[0]\n } else {\n range = selection.getRangeAt(0)\n }\n\n const caretContainer = range.startContainer\n const caretOffset = range.startOffset\n\n // Ensure the caret is within our editor element\n if (!this.editorElement.contains(caretContainer)) {\n this.hideSuggestions()\n return\n }\n\n // Only look for triggers in text nodes\n if (caretContainer.nodeType !== Node.TEXT_NODE) {\n this.hideSuggestions()\n return\n }\n\n const textContent = caretContainer.textContent || ''\n\n // Look backwards from caret to find mention trigger\n let mentionStart = -1\n for (let i = caretOffset - 1; i >= 0; i--) {\n const char = textContent[i]\n if (char === this.mentionTrigger) {\n mentionStart = i\n break\n }\n if (char === ' ' || char === '\\n') {\n break\n }\n }\n if (mentionStart >= 0) {\n const query = textContent.substring(mentionStart + 1, caretOffset)\n\n if (query.length >= this.minQueryLength) {\n this.currentMentionQuery = query\n this.currentMentionStart = this.getGlobalTextPosition(caretContainer, mentionStart)\n this.showSuggestions()\n this.updateFilteredSuggestions()\n } else {\n this.hideSuggestions()\n }\n } else {\n this.hideSuggestions()\n }\n }\n\n private walkerNodeFilter(node: Node): number {\n if (node.nodeType === Node.TEXT_NODE) {\n return NodeFilter.FILTER_ACCEPT\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element\n if (element.classList.contains('mention-chip')) {\n // Accept mention chips as single characters\n return NodeFilter.FILTER_ACCEPT\n } else if (element.parentElement?.classList.contains('mention-chip')) {\n // It's a chip, ignore the entire tree\n return NodeFilter.FILTER_REJECT\n }\n }\n return NodeFilter.FILTER_SKIP\n }\n\n /**\n * Gets the global text position within the editor for a position within a text node\n */\n private getGlobalTextPosition(textNode: Node, offsetInNode: number): number {\n let position = 0\n const walker = document.createTreeWalker(this.editorElement, ShowMask, this.walkerNodeFilter)\n\n let node = walker.nextNode()\n while (node && node !== textNode) {\n if (node.nodeType === Node.TEXT_NODE) {\n position += node.textContent?.length || 0\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element\n if (element.classList?.contains('mention-chip')) {\n position += 1 // Count chip as 1 character\n }\n }\n node = walker.nextNode()\n }\n\n return position + offsetInNode\n }\n\n /**\n * Finds the DOM node and offset that corresponds to a global text position\n */\n private findNodeAtGlobalPosition(globalPosition: number): { node: Node; offset: number } | null {\n let currentPosition = 0\n const walker = document.createTreeWalker(this.editorElement, ShowMask, this.walkerNodeFilter)\n\n let node = walker.nextNode()\n while (node) {\n if (node.nodeType === Node.TEXT_NODE) {\n const textLength = node.textContent?.length || 0\n if (currentPosition + textLength >= globalPosition) {\n return {\n node,\n offset: globalPosition - currentPosition,\n }\n }\n currentPosition += textLength\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element\n if (element.classList?.contains('mention-chip')) {\n if (currentPosition === globalPosition) {\n // Position is right before the chip\n const parentNode = element.parentNode\n if (parentNode) {\n return {\n node: parentNode,\n offset: Array.from(parentNode.childNodes).indexOf(element),\n }\n }\n }\n currentPosition += 1 // Count chip as 1 character\n }\n }\n node = walker.nextNode()\n }\n\n // Position is beyond the end, return the last position\n const lastChild = this.editorElement.lastChild\n if (lastChild) {\n if (lastChild.nodeType === Node.TEXT_NODE) {\n return {\n node: lastChild,\n offset: lastChild.textContent?.length || 0,\n }\n } else {\n return {\n node: this.editorElement,\n offset: this.editorElement.childNodes.length,\n }\n }\n }\n\n return null\n }\n\n /**\n * Shows the suggestions popover\n */\n private showSuggestions(): void {\n if (!this.isShowingSuggestions) {\n this.isShowingSuggestions = true\n this.selectedSuggestionIndex = 0\n this.updateContentState()\n\n // Use Popover API to show the popover\n this.updateComplete.then(() => {\n if (this.suggestionsPopover) {\n this.suggestionsPopover.showPopover()\n this.positionSuggestions()\n }\n })\n }\n }\n\n /**\n * Hides the suggestions popover\n */\n private hideSuggestions(): void {\n if (this.isShowingSuggestions) {\n this.isShowingSuggestions = false\n this.currentMentionQuery = ''\n this.currentMentionStart = -1\n this.updateContentState()\n\n // Use Popover API to hide the popover\n if (this.suggestionsPopover) {\n this.suggestionsPopover.hidePopover()\n }\n }\n }\n\n /**\n * Updates filtered suggestions based on current query\n */\n private updateFilteredSuggestions(): void {\n if (!this.currentMentionQuery) {\n this.filteredSuggestions = this.suggestions.slice(0, 10) // Limit to 10\n return\n }\n\n const query = this.currentMentionQuery.toLowerCase()\n this.filteredSuggestions = this.suggestions\n .filter(\n (suggestion) =>\n suggestion.label.toLowerCase().includes(query) ||\n suggestion.description?.toLowerCase().includes(query) ||\n suggestion.suffix?.toLowerCase().includes(query)\n )\n .slice(0, 10) // Limit to 10\n\n // Reset selection if needed\n if (this.selectedSuggestionIndex >= this.filteredSuggestions.length) {\n this.selectedSuggestionIndex = 0\n }\n }\n\n /**\n * Positions the suggestions popover using the Popover API anchor positioning\n */\n private positionSuggestions(): void {\n if (!this.suggestionsPopover) return\n\n const selection = window.getSelection()\n if (!selection || selection.rangeCount === 0) return\n\n // Use getComposedRanges() for shadow DOM support, fallback to getRangeAt()\n let range: Range | StaticRange\n if ('getComposedRanges' in selection && typeof selection.getComposedRanges === 'function' && this.shadowRoot) {\n const composedRanges = selection.getComposedRanges({ shadowRoots: [this.shadowRoot] })\n if (composedRanges.length === 0) return\n range = composedRanges[0]\n } else {\n range = selection.getRangeAt(0)\n }\n\n // Convert StaticRange to Range if needed for getBoundingClientRect\n let workingRange: Range\n if (range instanceof StaticRange) {\n workingRange = document.createRange()\n workingRange.setStart(range.startContainer, range.startOffset)\n workingRange.setEnd(range.endContainer, range.endOffset)\n } else {\n workingRange = range\n }\n\n const rect = workingRange.getBoundingClientRect()\n\n // Position suggestions below the caret using manual positioning as fallback\n // The Popover API will handle proper layering and overflow handling\n this.suggestionsPopover.style.left = `${rect.left}px`\n this.suggestionsPopover.style.top = `${rect.bottom + 4}px`\n }\n\n /**\n * Selects a suggestion and inserts it as a mention\n */\n private selectSuggestion(suggestion: MentionSuggestion): void {\n if (!suggestion) return\n\n // Add to mention map\n this.mentionMap.set(suggestion.id, suggestion)\n\n // Find the position where the mention trigger starts\n const mentionStart = this.currentMentionStart\n\n // Find the DOM node and offset for the mention start position\n const mentionStartInfo = this.findNodeAtGlobalPosition(mentionStart)\n\n if (!mentionStartInfo) {\n // Fallback: insert at the end\n const chip = this.createMentionChip(suggestion)\n const afterTextNode = document.createTextNode('')\n this.editorElement.appendChild(chip)\n this.editorElement.appendChild(afterTextNode)\n this.setCaretPositionAtTextNode(afterTextNode, 0)\n this.hideSuggestions()\n this.syncValueFromEditor()\n this.dispatchEvent(\n new CustomEvent<MentionInsertEvent>('mention-insert', {\n detail: {\n suggestion,\n trigger: this.mentionTrigger + this.currentMentionQuery,\n position: mentionStart,\n },\n bubbles: true,\n })\n )\n return\n }\n\n // If the target is not a text node, insert at the container level\n if (mentionStartInfo.node.nodeType !== Node.TEXT_NODE) {\n const chip = this.createMentionChip(suggestion)\n const container = mentionStartInfo.node\n const beforeNode = container.childNodes[mentionStartInfo.offset]\n\n // Create an empty text node for caret positioning\n const afterTextNode = document.createTextNode('')\n\n if (beforeNode) {\n container.insertBefore(chip, beforeNode)\n container.insertBefore(afterTextNode, beforeNode)\n } else {\n container.appendChild(chip)\n container.appendChild(afterTextNode)\n }\n\n // Position caret at the beginning of the after text node\n this.setCaretPositionAtTextNode(afterTextNode, 0)\n this.hideSuggestions()\n this.syncValueFromEditor()\n this.dispatchEvent(\n new CustomEvent<MentionInsertEvent>('mention-insert', {\n detail: {\n suggestion,\n trigger: this.mentionTrigger + this.currentMentionQuery,\n position: mentionStart,\n },\n bubbles: true,\n })\n )\n return\n }\n\n // We have a text node - split it and insert the chip\n const textNode = mentionStartInfo.node as Text\n const splitOffset = mentionStartInfo.offset\n\n // Create the mention chip\n const chip = this.createMentionChip(suggestion)\n\n // Split the text node at the mention start position\n const beforeText = textNode.textContent?.substring(0, splitOffset) || ''\n const afterText = textNode.textContent?.substring(splitOffset + 1) || '' // +1 to skip the trigger\n\n // Replace the original text node with the split content\n const parentNode = textNode.parentNode\n if (parentNode) {\n // Create new text nodes - always create afterTextNode even if empty\n const beforeTextNode = beforeText ? document.createTextNode(beforeText) : null\n const afterTextNode = document.createTextNode(afterText) // Always create, even if empty\n\n // Insert the nodes in order\n if (beforeTextNode) {\n parentNode.insertBefore(beforeTextNode, textNode)\n }\n parentNode.insertBefore(chip, textNode)\n parentNode.insertBefore(afterTextNode, textNode)\n\n // Remove the original text node\n parentNode.removeChild(textNode)\n\n // Position caret at the beginning of the after text node\n this.setCaretPositionAtTextNode(afterTextNode, 0)\n } else {\n // Fallback: append to editor and create a text node for caret positioning\n const afterTextNode = document.createTextNode('')\n this.editorElement.appendChild(chip)\n this.editorElement.appendChild(afterTextNode)\n this.setCaretPositionAtTextNode(afterTextNode, 0)\n }\n\n // Hide suggestions\n this.hideSuggestions()\n\n // Sync value and dispatch events\n this.syncValueFromEditor()\n this.dispatchEvent(\n new CustomEvent<MentionInsertEvent>('mention-insert', {\n detail: {\n suggestion,\n trigger: this.mentionTrigger + this.currentMentionQuery,\n position: mentionStart,\n },\n bubbles: true,\n })\n )\n }\n\n /**\n * Removes a mention chip\n */\n private removeMention(chipElement: HTMLElement, mention: MentionSuggestion): void {\n const position = this.getElementPosition(chipElement)\n chipElement.remove()\n\n this.syncValueFromEditor()\n this.dispatchEvent(\n new CustomEvent<MentionRemoveEvent>('mention-remove', {\n detail: {\n suggestion: mention,\n position,\n },\n bubbles: true,\n })\n )\n }\n\n /**\n * Gets the text position of an element\n */\n private getElementPosition(element: HTMLElement): number {\n let position = 0\n let currentNode = this.editorElement.firstChild\n\n while (currentNode && currentNode !== element) {\n if (currentNode.nodeType === Node.TEXT_NODE) {\n position += currentNode.textContent?.length || 0\n } else if (currentNode.nodeType === Node.ELEMENT_NODE) {\n const element = currentNode as Element\n if (element.classList?.contains('mention-chip')) {\n position += 1 // Count chip as 1 character\n }\n }\n currentNode = currentNode.nextSibling\n }\n\n return position\n }\n\n /**\n * Handles clicking on a suggestion\n */\n private handleSuggestionClick(suggestion: MentionSuggestion, event: Event): void {\n event.preventDefault()\n this.selectSuggestion(suggestion)\n this.focus()\n }\n\n /**\n * Renders a suggestion item\n */\n private renderSuggestion(suggestion: MentionSuggestion, index: number): TemplateResult {\n const isSelected = index === this.selectedSuggestionIndex\n const classes = classMap({\n 'suggestion-item': true,\n 'selected': isSelected,\n })\n\n return html`\n <button\n class=\"${classes}\"\n @click=\"${(e: Event) => this.handleSuggestionClick(suggestion, e)}\"\n @mouseenter=\"${() => (this.selectedSuggestionIndex = index)}\"\n >\n <div class=\"suggestion-content\">\n <div class=\"suggestion-headline\">${suggestion.label}</div>\n ${suggestion.description\n ? html` <div class=\"suggestion-supporting-text\">${suggestion.description}</div> `\n : nothing}\n </div>\n ${suggestion.suffix ? html` <div class=\"suggestion-suffix\">${suggestion.suffix}</div> ` : nothing}\n </button>\n `\n }\n\n /**\n * Renders the suggestions popover\n */\n private renderSuggestions(): TemplateResult {\n return html`\n <div class=\"suggestions-popover\" popover=\"manual\">\n ${this.isShowingSuggestions && this.filteredSuggestions.length > 0\n ? this.filteredSuggestions.map((suggestion, index) => this.renderSuggestion(suggestion, index))\n : nothing}\n </div>\n `\n }\n\n override render(): TemplateResult {\n const surfaceClasses = classMap({\n 'surface': true,\n 'has-content': this.hasContent,\n })\n\n const labelClasses = classMap({\n label: true,\n floating: this.isLabelFloating,\n })\n\n return html`\n <div class=\"${surfaceClasses}\">\n <div class=\"container\"></div>\n <div class=\"content\">\n <div class=\"body\">\n ${this.label ? html`<div class=\"${labelClasses}\">${this.label}</div>` : nothing}\n <div\n class=\"editor\"\n contenteditable=\"${!this.disabled}\"\n data-placeholder=\"${ifDefined(this.placeholder)}\"\n @input=\"${this.handleEditorInput}\"\n @keydown=\"${this.handleEditorKeyDown}\"\n @focus=\"${this.handleEditorFocus}\"\n @blur=\"${this.handleEditorBlur}\"\n @paste=\"${this.handleEditorPaste}\"\n role=\"textbox\"\n aria-label=\"${ifDefined(this.label)}\"\n aria-multiline=\"true\"\n aria-required=\"${this.required}\"\n aria-invalid=\"${this.invalid}\"\n tabindex=\"${this.disabled ? -1 : 0}\"\n ></div>\n </div>\n </div>\n ${this.renderSuggestions()}\n </div>\n ${this.supportingText ? html` <div class=\"supporting-text\">${this.supportingText}</div> ` : nothing}\n `\n }\n}\n"]}
@@ -5,7 +5,7 @@ export default css `
5
5
  }
6
6
 
7
7
  dialog {
8
- overflow: hidden;
8
+ overflow: auto;
9
9
  /* Do not override the display value here. It will render the dialog even when hidden */
10
10
 
11
11
  border: none;
@@ -50,7 +50,7 @@ export default css `
50
50
  display: flex;
51
51
  flex-direction: column;
52
52
  flex: 1;
53
- overflow: hidden;
53
+ /* overflow: hidden; */
54
54
  }
55
55
 
56
56
  .icon {
@@ -97,7 +97,7 @@ export default css `
97
97
  }
98
98
 
99
99
  .content {
100
- overflow: auto;
100
+ /* overflow: auto; */
101
101
  font-family: var(--md-sys-typescale-body-medium-font);
102
102
  font-weight: var(--md-sys-typescale-body-medium-weight);
103
103
  font-size: var(--md-sys-typescale-body-medium-size);
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.styles.js","sourceRoot":"","sources":["../../../../../src/md/dialog/internals/Dialog.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,eAAe,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkKjB,CAAA","sourcesContent":["import { css } from 'lit'\n\nexport default css`\n :host {\n display: contents;\n }\n\n dialog {\n overflow: hidden;\n /* Do not override the display value here. It will render the dialog even when hidden */\n\n border: none;\n border-radius: var(--md-sys-shape-corner-extra-large);\n background-color: var(--md-sys-color-surface-container-high);\n box-shadow: var(--md-sys-elevation-3);\n color: var(--md-sys-color-on-surface-variant);\n padding: 24px;\n\n max-width: var(--ui-dialog-max-width, 90vw);\n max-height: var(--ui-dialog-max-height, 90vh);\n width: var(--ui-dialog-width, revert);\n height: var(--ui-dialog-height, revert);\n }\n\n dialog:open {\n animation: 250ms cubic-bezier(0.2, 0, 0, 1) show-dialog;\n display: flex;\n flex-direction: column;\n }\n\n /* Positioning for non-modal dialogs */\n dialog.non-modal {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n margin: 0;\n z-index: 1000;\n }\n\n dialog.non-modal:open {\n /* Override the animation transform for non-modal dialogs to account for centering */\n animation: 250ms cubic-bezier(0.2, 0, 0, 1) show-non-modal-dialog;\n }\n\n dialog:open::backdrop {\n animation: 250ms cubic-bezier(0.2, 0, 0, 1) show-backdrop;\n }\n\n .container {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n }\n\n .icon {\n display: none;\n }\n\n .icon.with-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 16px;\n }\n\n .icon ::slotted(*) {\n color: var(--md-sys-color-secondary);\n fill: var(--md-sys-color-secondary);\n width: 24px;\n height: 24px;\n }\n\n .icon.destructive ::slotted(*) {\n color: var(--md-sys-color-error);\n fill: var(--md-sys-color-error);\n }\n\n .title {\n display: none;\n color: var(--md-sys-color-on-surface);\n font-family: var(--md-sys-typescale-headline-small-font);\n font-weight: var(--md-sys-typescale-headline-small-weight);\n font-size: var(--md-sys-typescale-headline-small-size);\n letter-spacing: var(--md-sys-typescale-headline-small-tracking);\n line-height: var(--md-sys-typescale-headline-small-height);\n margin: 0;\n padding: 0;\n text-align: center;\n }\n\n .title.with-title {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 16px;\n }\n\n .content {\n overflow: auto;\n font-family: var(--md-sys-typescale-body-medium-font);\n font-weight: var(--md-sys-typescale-body-medium-weight);\n font-size: var(--md-sys-typescale-body-medium-size);\n letter-spacing: var(--md-sys-typescale-body-medium-tracking);\n line-height: var(--md-sys-typescale-body-medium-height);\n }\n\n .buttons {\n display: none;\n display: flex;\n align-items: center;\n justify-content: end;\n }\n\n .buttons.with-buttons {\n margin-top: 24px;\n }\n\n .buttons ::slotted(:not(:last-child)) {\n margin-right: 12px;\n }\n\n .content ::slotted(*) {\n background-color: var(--md-sys-color-surface-container-high);\n }\n\n @keyframes show-dialog {\n from {\n transform: translateY(-110%) scaleY(0);\n }\n to {\n transform: translateY(0%) scaleY(1);\n }\n }\n\n @keyframes show-non-modal-dialog {\n from {\n transform: translate(-50%, -50%) translateY(-110%) scaleY(0);\n }\n to {\n transform: translate(-50%, -50%) translateY(0%) scaleY(1);\n }\n }\n\n @keyframes show-backdrop {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n /* Destructive button styling for dangerous actions */\n .internal-button.destructive {\n --_background-color: var(--md-sys-color-error);\n --_color: var(--md-sys-color-on-error);\n\n /* Override ripple colors for better interaction feedback */\n --md-ripple-hover-state-layer-color: var(--md-sys-color-on-error);\n --md-ripple-focus-state-layer-color: var(--md-sys-color-on-error);\n --md-ripple-pressed-state-layer-color: var(--md-sys-color-on-error);\n }\n`\n"]}
1
+ {"version":3,"file":"Dialog.styles.js","sourceRoot":"","sources":["../../../../../src/md/dialog/internals/Dialog.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAEzB,eAAe,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkKjB,CAAA","sourcesContent":["import { css } from 'lit'\n\nexport default css`\n :host {\n display: contents;\n }\n\n dialog {\n overflow: auto;\n /* Do not override the display value here. It will render the dialog even when hidden */\n\n border: none;\n border-radius: var(--md-sys-shape-corner-extra-large);\n background-color: var(--md-sys-color-surface-container-high);\n box-shadow: var(--md-sys-elevation-3);\n color: var(--md-sys-color-on-surface-variant);\n padding: 24px;\n\n max-width: var(--ui-dialog-max-width, 90vw);\n max-height: var(--ui-dialog-max-height, 90vh);\n width: var(--ui-dialog-width, revert);\n height: var(--ui-dialog-height, revert);\n }\n\n dialog:open {\n animation: 250ms cubic-bezier(0.2, 0, 0, 1) show-dialog;\n display: flex;\n flex-direction: column;\n }\n\n /* Positioning for non-modal dialogs */\n dialog.non-modal {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n margin: 0;\n z-index: 1000;\n }\n\n dialog.non-modal:open {\n /* Override the animation transform for non-modal dialogs to account for centering */\n animation: 250ms cubic-bezier(0.2, 0, 0, 1) show-non-modal-dialog;\n }\n\n dialog:open::backdrop {\n animation: 250ms cubic-bezier(0.2, 0, 0, 1) show-backdrop;\n }\n\n .container {\n display: flex;\n flex-direction: column;\n flex: 1;\n /* overflow: hidden; */\n }\n\n .icon {\n display: none;\n }\n\n .icon.with-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 16px;\n }\n\n .icon ::slotted(*) {\n color: var(--md-sys-color-secondary);\n fill: var(--md-sys-color-secondary);\n width: 24px;\n height: 24px;\n }\n\n .icon.destructive ::slotted(*) {\n color: var(--md-sys-color-error);\n fill: var(--md-sys-color-error);\n }\n\n .title {\n display: none;\n color: var(--md-sys-color-on-surface);\n font-family: var(--md-sys-typescale-headline-small-font);\n font-weight: var(--md-sys-typescale-headline-small-weight);\n font-size: var(--md-sys-typescale-headline-small-size);\n letter-spacing: var(--md-sys-typescale-headline-small-tracking);\n line-height: var(--md-sys-typescale-headline-small-height);\n margin: 0;\n padding: 0;\n text-align: center;\n }\n\n .title.with-title {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 16px;\n }\n\n .content {\n /* overflow: auto; */\n font-family: var(--md-sys-typescale-body-medium-font);\n font-weight: var(--md-sys-typescale-body-medium-weight);\n font-size: var(--md-sys-typescale-body-medium-size);\n letter-spacing: var(--md-sys-typescale-body-medium-tracking);\n line-height: var(--md-sys-typescale-body-medium-height);\n }\n\n .buttons {\n display: none;\n display: flex;\n align-items: center;\n justify-content: end;\n }\n\n .buttons.with-buttons {\n margin-top: 24px;\n }\n\n .buttons ::slotted(:not(:last-child)) {\n margin-right: 12px;\n }\n\n .content ::slotted(*) {\n background-color: var(--md-sys-color-surface-container-high);\n }\n\n @keyframes show-dialog {\n from {\n transform: translateY(-110%) scaleY(0);\n }\n to {\n transform: translateY(0%) scaleY(1);\n }\n }\n\n @keyframes show-non-modal-dialog {\n from {\n transform: translate(-50%, -50%) translateY(-110%) scaleY(0);\n }\n to {\n transform: translate(-50%, -50%) translateY(0%) scaleY(1);\n }\n }\n\n @keyframes show-backdrop {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n\n /* Destructive button styling for dangerous actions */\n .internal-button.destructive {\n --_background-color: var(--md-sys-color-error);\n --_color: var(--md-sys-color-on-error);\n\n /* Override ripple colors for better interaction feedback */\n --md-ripple-hover-state-layer-color: var(--md-sys-color-on-error);\n --md-ripple-focus-state-layer-color: var(--md-sys-color-on-error);\n --md-ripple-pressed-state-layer-color: var(--md-sys-color-on-error);\n }\n`\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api-client/ui",
3
- "version": "0.5.8",
3
+ "version": "0.5.10",
4
4
  "description": "Internal UI component library for the API Client ecosystem.",
5
5
  "license": "UNLICENSED",
6
6
  "main": "build/src/index.js",
@@ -181,6 +181,22 @@ export default class MentionTextArea extends LitElement {
181
181
  private mutationObserver?: MutationObserver
182
182
  private _value = '' // Internal value storage
183
183
 
184
+ /**
185
+ * A read-only list of the names of the fields currently mentioned in the textarea.
186
+ */
187
+ get mentions(): string[] {
188
+ const dependencies = new Set<string>()
189
+ if (!this.value) {
190
+ return []
191
+ }
192
+ const regex = /@\{([^}]+)\}/g
193
+ let match: RegExpExecArray | null
194
+ while ((match = regex.exec(this.value)) !== null) {
195
+ dependencies.add(match[1])
196
+ }
197
+ return Array.from(dependencies)
198
+ }
199
+
184
200
  override connectedCallback(): void {
185
201
  super.connectedCallback()
186
202
 
@@ -230,6 +246,22 @@ export default class MentionTextArea extends LitElement {
230
246
  }
231
247
  }
232
248
 
249
+ /**
250
+ * Get the plain text content without field references
251
+ * @returns The plain text content with field names instead of references
252
+ */
253
+ public getPlainText(): string {
254
+ let text = this.value
255
+
256
+ // Replace field references with their display names
257
+ text = text.replace(/@\{([^}]+)\}/g, (match, fieldId) => {
258
+ const field = this.suggestions.find((f) => f.id === fieldId)
259
+ return field ? field.label : fieldId
260
+ })
261
+
262
+ return text
263
+ }
264
+
233
265
  /**
234
266
  * Sets the caret position at the beginning of a specific text node
235
267
  */
@@ -6,7 +6,7 @@ export default css`
6
6
  }
7
7
 
8
8
  dialog {
9
- overflow: hidden;
9
+ overflow: auto;
10
10
  /* Do not override the display value here. It will render the dialog even when hidden */
11
11
 
12
12
  border: none;
@@ -51,7 +51,7 @@ export default css`
51
51
  display: flex;
52
52
  flex-direction: column;
53
53
  flex: 1;
54
- overflow: hidden;
54
+ /* overflow: hidden; */
55
55
  }
56
56
 
57
57
  .icon {
@@ -98,7 +98,7 @@ export default css`
98
98
  }
99
99
 
100
100
  .content {
101
- overflow: auto;
101
+ /* overflow: auto; */
102
102
  font-family: var(--md-sys-typescale-body-medium-font);
103
103
  font-weight: var(--md-sys-typescale-body-medium-weight);
104
104
  font-size: var(--md-sys-typescale-body-medium-size);
@@ -202,7 +202,6 @@ describe.skip('elements', () => {
202
202
  const event = e as CustomEvent<{
203
203
  path: string
204
204
  options: FileReadOptions
205
- // eslint-disable-next-line no-restricted-globals
206
205
  result: Promise<string | ArrayBuffer | Buffer>
207
206
  }>
208
207
  readOptions = event.detail.options
@@ -252,7 +251,6 @@ describe.skip('elements', () => {
252
251
  const event = e as CustomEvent<{
253
252
  path: string
254
253
  options: FileReadOptions
255
- // eslint-disable-next-line no-restricted-globals
256
254
  result: Promise<string | ArrayBuffer | Buffer>
257
255
  }>
258
256
  readOptions = event.detail.options
@@ -314,7 +312,6 @@ describe.skip('elements', () => {
314
312
  const event = e as CustomEvent<{
315
313
  path: string
316
314
  options: FileReadOptions
317
- // eslint-disable-next-line no-restricted-globals
318
315
  result: Promise<string | ArrayBuffer | Buffer>
319
316
  }>
320
317
  readOptions = event.detail.options
@@ -60,4 +60,55 @@ describe('MentionTextArea - Basic Tests', () => {
60
60
  assert.equal(editor.getAttribute('tabindex'), '-1')
61
61
  })
62
62
  })
63
+
64
+ describe('mentions getter - basic tests', () => {
65
+ it('should return empty array for empty value', async () => {
66
+ const element = await basicFixture()
67
+
68
+ assert.deepEqual(element.mentions, [])
69
+ })
70
+
71
+ it('should return empty array for text without mentions', async () => {
72
+ const element = await basicFixture()
73
+ element.value = 'Hello world'
74
+ await nextFrame()
75
+
76
+ assert.deepEqual(element.mentions, [])
77
+ })
78
+
79
+ it('should extract mention IDs from value', async () => {
80
+ const element = await basicFixture()
81
+ element.value = 'Hello @{user1} and @{user2}'
82
+ await nextFrame()
83
+
84
+ const mentions = element.mentions.sort()
85
+ assert.deepEqual(mentions, ['user1', 'user2'])
86
+ })
87
+ })
88
+
89
+ describe('getPlainText method - basic tests', () => {
90
+ it('should return same text when no mentions', async () => {
91
+ const element = await basicFixture()
92
+ element.value = 'Hello world'
93
+ await nextFrame()
94
+
95
+ assert.equal(element.getPlainText(), 'Hello world')
96
+ })
97
+
98
+ it('should replace mentions with IDs when no suggestions', async () => {
99
+ const element = await basicFixture()
100
+ element.value = 'Hello @{user1} world'
101
+ await nextFrame()
102
+
103
+ assert.equal(element.getPlainText(), 'Hello user1 world')
104
+ })
105
+
106
+ it('should handle empty value', async () => {
107
+ const element = await basicFixture()
108
+ element.value = ''
109
+ await nextFrame()
110
+
111
+ assert.equal(element.getPlainText(), '')
112
+ })
113
+ })
63
114
  })
@@ -318,4 +318,296 @@ describe('MentionTextArea', () => {
318
318
  assert.equal(mentionChips[1].getAttribute('data-mention-id'), 'user2')
319
319
  })
320
320
  })
321
+
322
+ describe('mentions getter', () => {
323
+ it('should return empty array when no mentions exist', async () => {
324
+ const element = await basicFixture()
325
+
326
+ element.value = 'Hello world without mentions'
327
+ await nextFrame()
328
+
329
+ assert.deepEqual(element.mentions, [])
330
+ })
331
+
332
+ it('should return single mention ID', async () => {
333
+ const element = await withSuggestionsFixture()
334
+
335
+ element.value = 'Hello @{user1} how are you?'
336
+ await nextFrame()
337
+
338
+ assert.deepEqual(element.mentions, ['user1'])
339
+ })
340
+
341
+ it('should return multiple unique mention IDs', async () => {
342
+ const element = await withSuggestionsFixture()
343
+
344
+ element.value = 'Hello @{user1} and @{user2}!'
345
+ await nextFrame()
346
+
347
+ assert.deepEqual(element.mentions.sort(), ['user1', 'user2'])
348
+ })
349
+
350
+ it('should deduplicate repeated mentions', async () => {
351
+ const element = await withSuggestionsFixture()
352
+
353
+ element.value = 'Hello @{user1}, @{user1} said @{user2} and @{user1} again'
354
+ await nextFrame()
355
+
356
+ const mentions = element.mentions.sort()
357
+ assert.deepEqual(mentions, ['user1', 'user2'])
358
+ assert.equal(mentions.length, 2)
359
+ })
360
+
361
+ it('should handle empty value', async () => {
362
+ const element = await withSuggestionsFixture()
363
+
364
+ element.value = ''
365
+ await nextFrame()
366
+
367
+ assert.deepEqual(element.mentions, [])
368
+ })
369
+
370
+ it('should handle malformed mentions', async () => {
371
+ const element = await withSuggestionsFixture()
372
+
373
+ element.value = 'Hello @{user1} and @{ } and @{valid_user}'
374
+ await nextFrame()
375
+
376
+ const mentions = element.mentions.sort()
377
+ assert.include(mentions, 'user1')
378
+ assert.include(mentions, ' ') // empty space is still captured
379
+ assert.include(mentions, 'valid_user')
380
+ assert.equal(mentions.length, 3)
381
+ })
382
+
383
+ it('should handle special characters in mention IDs', async () => {
384
+ const element = await withSuggestionsFixture()
385
+
386
+ element.value = 'Hello @{user-1} and @{user_2} and @{user.3}'
387
+ await nextFrame()
388
+
389
+ const mentions = element.mentions.sort()
390
+ assert.deepEqual(mentions, ['user-1', 'user.3', 'user_2'])
391
+ })
392
+
393
+ it('should handle unicode characters in mention IDs', async () => {
394
+ const element = await withSuggestionsFixture()
395
+
396
+ element.value = 'Hello @{user-🎉} and @{user_ñ} and @{用户1}'
397
+ await nextFrame()
398
+
399
+ const mentions = element.mentions.sort()
400
+ assert.deepEqual(mentions, ['user-🎉', 'user_ñ', '用户1'])
401
+ })
402
+
403
+ it('should handle nested curly braces gracefully', async () => {
404
+ const element = await withSuggestionsFixture()
405
+
406
+ element.value = 'Hello @{user{nested}} and @{user1}'
407
+ await nextFrame()
408
+
409
+ const mentions = element.mentions.sort()
410
+ // The regex matches @{user{nested}} as 'user{nested' and @{user1} as 'user1'
411
+ assert.include(mentions, 'user1')
412
+ assert.include(mentions, 'user{nested')
413
+ assert.equal(mentions.length, 2)
414
+ })
415
+
416
+ it('should handle very long mention IDs', async () => {
417
+ const element = await withSuggestionsFixture()
418
+ const longId = 'a'.repeat(1000)
419
+
420
+ element.value = `Hello @{${longId}} world`
421
+ await nextFrame()
422
+
423
+ const mentions = element.mentions
424
+ assert.include(mentions, longId)
425
+ assert.equal(mentions.length, 1)
426
+ })
427
+
428
+ it('should handle mentions at the beginning and end of text', async () => {
429
+ const element = await withSuggestionsFixture()
430
+
431
+ element.value = '@{user1} said hello to @{user2}'
432
+ await nextFrame()
433
+
434
+ const mentions = element.mentions.sort()
435
+ assert.deepEqual(mentions, ['user1', 'user2'])
436
+ })
437
+ })
438
+
439
+ describe('getPlainText method', () => {
440
+ it('should return plain text without mentions when no mentions exist', async () => {
441
+ const element = await basicFixture()
442
+
443
+ element.value = 'Hello world without mentions'
444
+ await nextFrame()
445
+
446
+ assert.equal(element.getPlainText(), 'Hello world without mentions')
447
+ })
448
+
449
+ it('should replace mention with field label when field exists in suggestions', async () => {
450
+ const element = await withSuggestionsFixture()
451
+
452
+ element.value = 'Hello @{user1} how are you?'
453
+ await nextFrame()
454
+
455
+ // user1 should be replaced with "John Doe" from suggestions
456
+ assert.equal(element.getPlainText(), 'Hello John Doe how are you?')
457
+ })
458
+
459
+ it('should replace multiple mentions with their labels', async () => {
460
+ const element = await withSuggestionsFixture()
461
+
462
+ element.value = 'Hello @{user1} and @{user2}!'
463
+ await nextFrame()
464
+
465
+ assert.equal(element.getPlainText(), 'Hello John Doe and Jane Smith!')
466
+ })
467
+
468
+ it('should keep original field name when field not found in suggestions', async () => {
469
+ const element = await withSuggestionsFixture()
470
+
471
+ element.value = 'Hello @{nonexistent} user'
472
+ await nextFrame()
473
+
474
+ assert.equal(element.getPlainText(), 'Hello nonexistent user')
475
+ })
476
+
477
+ it('should handle mixed existing and non-existing mentions', async () => {
478
+ const element = await withSuggestionsFixture()
479
+
480
+ element.value = 'Hello @{user1} and @{nonexistent} and @{user2}'
481
+ await nextFrame()
482
+
483
+ assert.equal(element.getPlainText(), 'Hello John Doe and nonexistent and Jane Smith')
484
+ })
485
+
486
+ it('should handle duplicate mentions correctly', async () => {
487
+ const element = await withSuggestionsFixture()
488
+
489
+ element.value = '@{user1} said hello to @{user1}'
490
+ await nextFrame()
491
+
492
+ assert.equal(element.getPlainText(), 'John Doe said hello to John Doe')
493
+ })
494
+
495
+ it('should handle empty value', async () => {
496
+ const element = await withSuggestionsFixture()
497
+
498
+ element.value = ''
499
+ await nextFrame()
500
+
501
+ assert.equal(element.getPlainText(), '')
502
+ })
503
+
504
+ it('should preserve text formatting and whitespace', async () => {
505
+ const element = await withSuggestionsFixture()
506
+
507
+ element.value = ' Hello @{user1},\n\nHow are you @{user2}? \n'
508
+ await nextFrame()
509
+
510
+ assert.equal(element.getPlainText(), ' Hello John Doe,\n\nHow are you Jane Smith? \n')
511
+ })
512
+
513
+ it('should handle mention-like text that is not a mention', async () => {
514
+ const element = await withSuggestionsFixture()
515
+
516
+ element.value = 'Use at{symbol} and @{user1}'
517
+ await nextFrame()
518
+
519
+ // Only @{user1} should be replaced, at{symbol} should remain as is
520
+ assert.equal(element.getPlainText(), 'Use at{symbol} and John Doe')
521
+ })
522
+
523
+ it('should find field by ID not label', async () => {
524
+ const element = await withSuggestionsFixture()
525
+
526
+ // Use the ID 'user1' which should match and return label 'John Doe'
527
+ element.value = 'Hello @{user1}'
528
+ await nextFrame()
529
+
530
+ assert.equal(element.getPlainText(), 'Hello John Doe')
531
+ })
532
+
533
+ it('should handle mention IDs with special characters', async () => {
534
+ const element = await withSuggestionsFixture()
535
+ // Add a suggestion with special characters in ID
536
+ element.suggestions = [
537
+ ...element.suggestions,
538
+ { id: 'user-special_123', label: 'Special User', description: 'Test user' },
539
+ ]
540
+
541
+ element.value = 'Hello @{user-special_123}'
542
+ await nextFrame()
543
+
544
+ assert.equal(element.getPlainText(), 'Hello Special User')
545
+ })
546
+
547
+ it('should handle unicode characters in mention IDs', async () => {
548
+ const element = await withSuggestionsFixture()
549
+ element.suggestions = [
550
+ ...element.suggestions,
551
+ { id: 'user-🎉', label: 'Party User', description: 'Celebration' },
552
+ { id: '用户1', label: 'Chinese User', description: 'Test' },
553
+ ]
554
+
555
+ element.value = 'Hello @{user-🎉} and @{用户1}'
556
+ await nextFrame()
557
+
558
+ assert.equal(element.getPlainText(), 'Hello Party User and Chinese User')
559
+ })
560
+
561
+ it('should handle complex text with multiple lines and mentions', async () => {
562
+ const element = await withSuggestionsFixture()
563
+
564
+ element.value = `Line 1 with @{user1}
565
+ Line 2 with @{user2}
566
+ Line 3 with @{user1} again`
567
+ await nextFrame()
568
+
569
+ const expected = `Line 1 with John Doe
570
+ Line 2 with Jane Smith
571
+ Line 3 with John Doe again`
572
+
573
+ assert.equal(element.getPlainText(), expected)
574
+ })
575
+
576
+ it('should handle malformed mentions gracefully', async () => {
577
+ const element = await withSuggestionsFixture()
578
+
579
+ element.value = 'Hello @{user1} and @{invalid and @{user2}'
580
+ await nextFrame()
581
+
582
+ // The regex matches @{user1} and @{invalid and @{user2} as one mention
583
+ // @{user1} gets replaced with "John Doe"
584
+ // @{invalid and @{user2} doesn't match any suggestion, so falls back to the field ID
585
+ assert.equal(element.getPlainText(), 'Hello John Doe and invalid and @{user2')
586
+ })
587
+
588
+ it('should handle empty suggestion array', async () => {
589
+ const element = await basicFixture()
590
+ element.suggestions = []
591
+
592
+ element.value = 'Hello @{user1} world'
593
+ await nextFrame()
594
+
595
+ // Should fallback to the mention ID since no suggestions available
596
+ assert.equal(element.getPlainText(), 'Hello user1 world')
597
+ })
598
+
599
+ it('should handle null and undefined values in suggestions', async () => {
600
+ const element = await withSuggestionsFixture()
601
+ element.suggestions = [
602
+ { id: 'user1', label: 'John Doe', description: 'Engineer' },
603
+ { id: 'user2', label: '', description: 'Empty label' }, // Empty label
604
+ { id: 'user3', label: 'Jane Smith' }, // No description
605
+ ]
606
+
607
+ element.value = 'Hello @{user1} and @{user2} and @{user3}'
608
+ await nextFrame()
609
+
610
+ assert.equal(element.getPlainText(), 'Hello John Doe and and Jane Smith')
611
+ })
612
+ })
321
613
  })