@tylertech/forge-ai 0.2.0 → 0.3.0

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.
Files changed (37) hide show
  1. package/custom-elements.json +282 -100
  2. package/dist/ai-actions-toolbar/ai-actions-toolbar.d.ts +3 -3
  3. package/dist/ai-chat-interface/ai-chat-interface.d.ts +2 -8
  4. package/dist/ai-chat-interface/ai-chat-interface.mjs +9 -92
  5. package/dist/ai-chat-interface/ai-chat-interface.scss.mjs +1 -1
  6. package/dist/ai-dialog/ai-dialog.d.ts +1 -0
  7. package/dist/ai-dialog/ai-dialog.mjs +30 -3
  8. package/dist/ai-dialog/ai-dialog.scss.mjs +1 -1
  9. package/dist/ai-dropdown-menu/ai-dropdown-menu.d.ts +0 -1
  10. package/dist/ai-dropdown-menu/ai-dropdown-menu.mjs +5 -7
  11. package/dist/ai-file-picker/ai-file-picker.d.ts +5 -5
  12. package/dist/ai-file-picker/ai-file-picker.mjs +16 -16
  13. package/dist/ai-file-picker/index.d.ts +1 -1
  14. package/dist/ai-file-picker/index.mjs +2 -2
  15. package/dist/ai-prompt/ai-prompt.d.ts +34 -6
  16. package/dist/ai-prompt/ai-prompt.mjs +109 -25
  17. package/dist/ai-prompt/ai-prompt.scss.mjs +1 -1
  18. package/dist/ai-response-message/ai-response-message.d.ts +3 -4
  19. package/dist/ai-response-message/ai-response-message.mjs +1 -6
  20. package/dist/ai-response-message/ai-response-message.scss.mjs +1 -1
  21. package/dist/ai-sidebar/ai-sidebar.d.ts +4 -0
  22. package/dist/ai-sidebar/ai-sidebar.mjs +32 -13
  23. package/dist/ai-sidebar/ai-sidebar.scss.mjs +1 -1
  24. package/dist/ai-suggestions/ai-suggestions.d.ts +3 -3
  25. package/dist/ai-suggestions/ai-suggestions.mjs +2 -2
  26. package/dist/ai-thinking-indicator/ai-thinking-indicator.d.ts +22 -0
  27. package/dist/ai-thinking-indicator/ai-thinking-indicator.mjs +41 -0
  28. package/dist/ai-thinking-indicator/ai-thinking-indicator.scss.mjs +4 -0
  29. package/dist/ai-thinking-indicator/index.d.ts +1 -0
  30. package/dist/ai-thinking-indicator/index.mjs +5 -0
  31. package/dist/ai-threads/ai-threads.d.ts +3 -3
  32. package/dist/ai-voice-input/ai-voice-input.d.ts +1 -1
  33. package/dist/core/overlay/overlay.scss.mjs +1 -1
  34. package/dist/core/popover/popover.mjs +1 -1
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.mjs +5 -2
  37. package/package.json +1 -1
@@ -21,56 +21,29 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
21
21
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
22
22
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
23
23
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
24
- var _headerSlot, _suggestionsSlot, _AiChatInterfaceComponent_instances, suggestions_get, _promptSlot, prompt_get, _messagesSlot, messagesContainer_get, handleSlotChange_fn, setupResizeObserver_fn, cleanupResizeObserver_fn, setupMutationObserver_fn, cleanupMutationObserver_fn, setupScrollListener_fn, cleanupScrollListener_fn;
24
+ var _headerSlot, _suggestionsSlot, _AiChatInterfaceComponent_instances, suggestions_get, _promptSlot, prompt_get, _messagesSlot, messagesContainer_get, handleSlotChange_fn;
25
25
  const AiChatInterfaceComponentTagName = "forge-ai-chat-interface";
26
26
  let AiChatInterfaceComponent = class extends LitElement {
27
27
  constructor() {
28
28
  super(...arguments);
29
29
  __privateAdd(this, _AiChatInterfaceComponent_instances);
30
30
  this._hasMessages = false;
31
- this._resizeObserver = null;
32
- this._mutationObserver = null;
33
- this._userHasScrolledUp = false;
34
- this._isScrollEventListenerAdded = false;
35
31
  __privateAdd(this, _headerSlot, html`<slot name="header" @slotchange=${__privateMethod(this, _AiChatInterfaceComponent_instances, handleSlotChange_fn)}></slot>`);
36
32
  __privateAdd(this, _suggestionsSlot, html`<slot name="suggestions" @slotchange=${__privateMethod(this, _AiChatInterfaceComponent_instances, handleSlotChange_fn)}></slot>`);
37
33
  __privateAdd(this, _promptSlot, html`<slot name="prompt" @slotchange=${__privateMethod(this, _AiChatInterfaceComponent_instances, handleSlotChange_fn)}></slot>`);
38
34
  __privateAdd(this, _messagesSlot, html`<slot @slotchange=${__privateMethod(this, _AiChatInterfaceComponent_instances, handleSlotChange_fn)}></slot>`);
39
35
  }
40
36
  /**
41
- * Scrolls the messages container to the bottom only if user hasn't scrolled up
37
+ * Scrolls the messages container to the bottom with smooth animation
42
38
  */
43
- scrollMessagesToBottom() {
39
+ scrollToBottom() {
44
40
  const messagesContainer = this.shadowRoot?.querySelector(".messages-container");
45
- if (!messagesContainer) {
46
- return;
41
+ if (messagesContainer) {
42
+ messagesContainer.scrollTo({
43
+ top: messagesContainer.scrollHeight,
44
+ behavior: "smooth"
45
+ });
47
46
  }
48
- const hasOverflow = messagesContainer.scrollHeight > messagesContainer.clientHeight;
49
- if (!hasOverflow) {
50
- messagesContainer.scrollTop = messagesContainer.scrollHeight;
51
- return;
52
- }
53
- if (hasOverflow && !this._isScrollEventListenerAdded) {
54
- __privateMethod(this, _AiChatInterfaceComponent_instances, setupScrollListener_fn).call(this, messagesContainer);
55
- }
56
- const tolerance = 5;
57
- const isAtBottom = messagesContainer.scrollTop + messagesContainer.clientHeight >= messagesContainer.scrollHeight - tolerance;
58
- if (isAtBottom) {
59
- this._userHasScrolledUp = false;
60
- }
61
- if (!this._userHasScrolledUp) {
62
- messagesContainer.scrollTop = messagesContainer.scrollHeight;
63
- }
64
- }
65
- firstUpdated() {
66
- __privateMethod(this, _AiChatInterfaceComponent_instances, setupResizeObserver_fn).call(this);
67
- __privateMethod(this, _AiChatInterfaceComponent_instances, setupMutationObserver_fn).call(this);
68
- }
69
- disconnectedCallback() {
70
- super.disconnectedCallback();
71
- __privateMethod(this, _AiChatInterfaceComponent_instances, cleanupResizeObserver_fn).call(this);
72
- __privateMethod(this, _AiChatInterfaceComponent_instances, cleanupMutationObserver_fn).call(this);
73
- __privateMethod(this, _AiChatInterfaceComponent_instances, cleanupScrollListener_fn).call(this);
74
47
  }
75
48
  render() {
76
49
  return html`
@@ -99,7 +72,7 @@ prompt_get = function() {
99
72
  _messagesSlot = /* @__PURE__ */ new WeakMap();
100
73
  messagesContainer_get = function() {
101
74
  return html`
102
- <div class="messages-container">
75
+ <div class="messages-container" part="messages">
103
76
  ${__privateGet(this, _messagesSlot)} ${!this._hasMessages ? html`<forge-ai-empty-state></forge-ai-empty-state>` : nothing}
104
77
  </div>
105
78
  `;
@@ -115,62 +88,6 @@ handleSlotChange_fn = function(evt) {
115
88
  this.requestUpdate();
116
89
  }
117
90
  };
118
- setupResizeObserver_fn = function() {
119
- const messagesContainer = this.shadowRoot?.querySelector(".messages-container");
120
- if (!messagesContainer) {
121
- return;
122
- }
123
- this._resizeObserver = new ResizeObserver(() => {
124
- requestAnimationFrame(() => {
125
- this.scrollMessagesToBottom();
126
- });
127
- });
128
- this._resizeObserver.observe(messagesContainer);
129
- };
130
- cleanupResizeObserver_fn = function() {
131
- if (this._resizeObserver) {
132
- this._resizeObserver.disconnect();
133
- this._resizeObserver = null;
134
- }
135
- };
136
- setupMutationObserver_fn = function() {
137
- this._mutationObserver = new MutationObserver(() => {
138
- requestAnimationFrame(() => {
139
- this.scrollMessagesToBottom();
140
- });
141
- });
142
- this._mutationObserver.observe(this, {
143
- childList: true,
144
- subtree: true,
145
- attributes: false,
146
- characterData: true
147
- });
148
- };
149
- cleanupMutationObserver_fn = function() {
150
- if (this._mutationObserver) {
151
- this._mutationObserver.disconnect();
152
- this._mutationObserver = null;
153
- }
154
- };
155
- setupScrollListener_fn = function(messagesContainer) {
156
- let lastScrollTop = messagesContainer.scrollTop;
157
- const handleScroll = () => {
158
- const currentScrollTop = messagesContainer.scrollTop;
159
- if (currentScrollTop < lastScrollTop) {
160
- this._userHasScrolledUp = true;
161
- }
162
- lastScrollTop = currentScrollTop;
163
- };
164
- messagesContainer.addEventListener("scroll", handleScroll, { passive: true });
165
- this._isScrollEventListenerAdded = true;
166
- };
167
- cleanupScrollListener_fn = function() {
168
- const messagesContainer = this.shadowRoot?.querySelector(".messages-container");
169
- if (messagesContainer && this._isScrollEventListenerAdded) {
170
- messagesContainer.replaceWith(messagesContainer.cloneNode(true));
171
- this._isScrollEventListenerAdded = false;
172
- }
173
- };
174
91
  AiChatInterfaceComponent.styles = unsafeCSS(styles);
175
92
  __decorateClass([
176
93
  queryAssignedNodes({ slot: "suggestions", flatten: true })
@@ -1,4 +1,4 @@
1
- const styles = '/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/* prettier-ignore */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n:host {\n display: block;\n height: 100%;\n flex-grow: 1;\n}\n\n.ai-chat-interface {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-body1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-body1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-body1-font-weight, 400);\n line-height: var(--forge-typography-body1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-body1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-body1-text-transform, inherit);\n text-decoration: var(--forge-typography-body1-text-decoration, inherit);\n color: var(--forge-theme-on-surface, #000000);\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.messages-container::-webkit-scrollbar {\n height: var(--forge-scrollbar-height, 16px);\n width: var(--forge-scrollbar-width, 16px);\n}\n.messages-container::-webkit-scrollbar-track {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.messages-container::-webkit-scrollbar-track:hover {\n background-color: var(--forge-scrollbar-track-container-hover, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.messages-container::-webkit-scrollbar-corner {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.messages-container::-webkit-scrollbar-thumb {\n height: var(--forge-scrollbar-thumb-min-height, 32px);\n width: var(--forge-scrollbar-thumb-min-width, 32px);\n border-radius: var(--forge-scrollbar-border-radius, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n border-width: var(--forge-scrollbar-border-width, 3px);\n border-style: solid;\n border-color: transparent;\n background-color: var(--forge-scrollbar-thumb-container, var(--forge-theme-surface-container-medium, #c2c2c2));\n background-clip: content-box;\n}\n.messages-container::-webkit-scrollbar-thumb:hover {\n background-color: var(--forge-scrollbar-thumb-container-hover, var(--forge-theme-surface-container-high, #9e9e9e));\n}\n.messages-container {\n padding-inline-start: var(--forge-spacing-medium, 16px);\n padding-block-end: var(--forge-spacing-medium, 16px);\n scrollbar-gutter: stable;\n scroll-behavior: smooth;\n overflow-y: auto;\n}\n@media not all and (min-resolution: 0.001dpcm) {\n @supports (-webkit-appearance: none) {\n .messages-container {\n overflow-y: scroll;\n }\n }\n}\n.messages-container {\n background: linear-gradient(to top, var(--forge-theme-primary-container-minimum, #f7f8fc), var(--forge-theme-surface, #ffffff));\n border-block-end: 1px solid var(--forge-theme-outline, #e0e0e0);\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n gap: var(--forge-spacing-medium, 16px);\n}\n\n.suggestions-container {\n padding-inline: var(--forge-spacing-medium, 16px);\n padding-block-start: var(--forge-spacing-medium, 16px);\n}\n\n.prompt-container {\n padding: var(--forge-spacing-medium, 16px);\n}';
1
+ const styles = '/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/* prettier-ignore */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n:host {\n display: block;\n height: 100%;\n flex-grow: 1;\n}\n\n.ai-chat-interface {\n -moz-osx-font-smoothing: grayscale;\n -webkit-font-smoothing: antialiased;\n font-family: var(--forge-typography-body1-font-family, var(--forge-typography-font-family, "Roboto", sans-serif));\n font-size: var(--forge-typography-body1-font-size, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-font-size-scale, 0.875)));\n font-weight: var(--forge-typography-body1-font-weight, 400);\n line-height: var(--forge-typography-body1-line-height, calc(var(--forge-typography-font-size, 1rem) * var(--forge-typography-body-line-height-scale, 1.125)));\n letter-spacing: var(--forge-typography-body1-letter-spacing, 0.0357142857em);\n text-transform: var(--forge-typography-body1-text-transform, inherit);\n text-decoration: var(--forge-typography-body1-text-decoration, inherit);\n color: var(--forge-theme-on-surface, #000000);\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.messages-container::-webkit-scrollbar {\n height: var(--forge-scrollbar-height, 16px);\n width: var(--forge-scrollbar-width, 16px);\n}\n.messages-container::-webkit-scrollbar-track {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.messages-container::-webkit-scrollbar-track:hover {\n background-color: var(--forge-scrollbar-track-container-hover, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.messages-container::-webkit-scrollbar-corner {\n background-color: var(--forge-scrollbar-track-container, var(--forge-theme-surface-container-low, #ebebeb));\n}\n.messages-container::-webkit-scrollbar-thumb {\n height: var(--forge-scrollbar-thumb-min-height, 32px);\n width: var(--forge-scrollbar-thumb-min-width, 32px);\n border-radius: var(--forge-scrollbar-border-radius, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n border-width: var(--forge-scrollbar-border-width, 3px);\n border-style: solid;\n border-color: transparent;\n background-color: var(--forge-scrollbar-thumb-container, var(--forge-theme-surface-container-medium, #c2c2c2));\n background-clip: content-box;\n}\n.messages-container::-webkit-scrollbar-thumb:hover {\n background-color: var(--forge-scrollbar-thumb-container-hover, var(--forge-theme-surface-container-high, #9e9e9e));\n}\n.messages-container {\n padding-inline: var(--forge-spacing-medium, 16px);\n padding-block-end: var(--forge-spacing-medium, 16px);\n overflow-y: auto;\n}\n@media not all and (min-resolution: 0.001dpcm) {\n @supports (-webkit-appearance: none) {\n .messages-container {\n overflow-y: scroll;\n }\n }\n}\n.messages-container {\n background: linear-gradient(to top, var(--forge-theme-primary-container-minimum, #f7f8fc), var(--forge-theme-surface, #ffffff));\n border-block-end: 1px solid var(--forge-theme-outline, #e0e0e0);\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n gap: var(--forge-spacing-medium, 16px);\n}\n\n.suggestions-container {\n padding-inline: var(--forge-spacing-medium, 16px);\n padding-block-start: var(--forge-spacing-medium, 16px);\n}\n\n.prompt-container {\n padding: var(--forge-spacing-medium, 16px);\n}';
2
2
  export {
3
3
  styles as default
4
4
  };
@@ -33,6 +33,7 @@ export declare class AiDialogComponent extends LitElement {
33
33
  */
34
34
  expanded: boolean;
35
35
  private _isFullscreen;
36
+ private _isClosing;
36
37
  /**
37
38
  * Gets the current fullscreen state (readonly)
38
39
  */
@@ -23,8 +23,9 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
23
23
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
24
24
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
25
25
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
26
- var _mediaQuery, _popoverElementRef, _aiModalElementRef, _dragHandleRef, _escapeKeyAbortController, _dragController, _content, _AiDialogComponent_instances, popoverTemplate_get, modalTemplate_get, setupMediaQuery_fn, setupDragController_fn, cleanupMediaQuery_fn, _handleMediaChange, handleOpenStateChange_fn, handlePopoverToggle_fn, handleDialogClose_fn, addEscapeKeyListener_fn, removeEscapeKeyListener_fn, _handleKeyDown;
26
+ var _mediaQuery, _popoverElementRef, _aiModalElementRef, _dragHandleRef, _escapeKeyAbortController, _dragController, _closeTimeout, _content, _AiDialogComponent_instances, popoverTemplate_get, modalTemplate_get, setupMediaQuery_fn, setupDragController_fn, cleanupMediaQuery_fn, _handleMediaChange, handleOpenStateChange_fn, handlePopoverToggle_fn, handleDialogClose_fn, addEscapeKeyListener_fn, removeEscapeKeyListener_fn, _handleKeyDown;
27
27
  const VIEWPORT_WIDTH_THRESHOLD = 768;
28
+ const CLOSE_ANIMATION_DURATION = 100;
28
29
  const AiDialogComponentTagName = "forge-ai-dialog";
29
30
  let AiDialogComponent = class extends LitElement {
30
31
  constructor() {
@@ -33,12 +34,14 @@ let AiDialogComponent = class extends LitElement {
33
34
  this.open = false;
34
35
  this.expanded = false;
35
36
  this._isFullscreen = window.innerWidth <= VIEWPORT_WIDTH_THRESHOLD;
37
+ this._isClosing = false;
36
38
  __privateAdd(this, _mediaQuery);
37
39
  __privateAdd(this, _popoverElementRef, createRef());
38
40
  __privateAdd(this, _aiModalElementRef, createRef());
39
41
  __privateAdd(this, _dragHandleRef, createRef());
40
42
  __privateAdd(this, _escapeKeyAbortController);
41
43
  __privateAdd(this, _dragController);
44
+ __privateAdd(this, _closeTimeout);
42
45
  __privateAdd(this, _content, html`<slot></slot>`);
43
46
  __privateAdd(this, _handleMediaChange, (e) => {
44
47
  const previousFullscreen = this._isFullscreen;
@@ -79,6 +82,10 @@ let AiDialogComponent = class extends LitElement {
79
82
  super.disconnectedCallback();
80
83
  __privateMethod(this, _AiDialogComponent_instances, cleanupMediaQuery_fn).call(this);
81
84
  __privateMethod(this, _AiDialogComponent_instances, removeEscapeKeyListener_fn).call(this);
85
+ if (__privateGet(this, _closeTimeout)) {
86
+ clearTimeout(__privateGet(this, _closeTimeout));
87
+ __privateSet(this, _closeTimeout, void 0);
88
+ }
82
89
  }
83
90
  updated(changedProperties) {
84
91
  super.updated(changedProperties);
@@ -140,16 +147,22 @@ _aiModalElementRef = /* @__PURE__ */ new WeakMap();
140
147
  _dragHandleRef = /* @__PURE__ */ new WeakMap();
141
148
  _escapeKeyAbortController = /* @__PURE__ */ new WeakMap();
142
149
  _dragController = /* @__PURE__ */ new WeakMap();
150
+ _closeTimeout = /* @__PURE__ */ new WeakMap();
143
151
  _content = /* @__PURE__ */ new WeakMap();
144
152
  _AiDialogComponent_instances = /* @__PURE__ */ new WeakSet();
145
153
  popoverTemplate_get = function() {
154
+ const dialogClasses = [
155
+ "ai-dialog",
156
+ __privateGet(this, _dragController)?.isDragging ? "dragging" : "",
157
+ this._isClosing ? "closing" : ""
158
+ ].filter(Boolean).join(" ");
146
159
  return html`
147
160
  <dialog
148
161
  ${ref(__privateGet(this, _popoverElementRef))}
149
162
  aria-modal="false"
150
163
  aria-labelledby="dialog-title"
151
164
  popover="manual"
152
- class="ai-dialog ${__privateGet(this, _dragController)?.isDragging ? "dragging" : ""}"
165
+ class="${dialogClasses}"
153
166
  @toggle=${__privateMethod(this, _AiDialogComponent_instances, handlePopoverToggle_fn)}>
154
167
  <button
155
168
  ${ref(__privateGet(this, _dragHandleRef))}
@@ -197,8 +210,13 @@ cleanupMediaQuery_fn = function() {
197
210
  _handleMediaChange = /* @__PURE__ */ new WeakMap();
198
211
  handleOpenStateChange_fn = function() {
199
212
  const useDialog = this._isFullscreen || this.expanded;
213
+ if (__privateGet(this, _closeTimeout)) {
214
+ clearTimeout(__privateGet(this, _closeTimeout));
215
+ __privateSet(this, _closeTimeout, void 0);
216
+ }
200
217
  if (useDialog) {
201
218
  __privateMethod(this, _AiDialogComponent_instances, removeEscapeKeyListener_fn).call(this);
219
+ this._isClosing = false;
202
220
  const dialogElement = __privateGet(this, _aiModalElementRef).value;
203
221
  if (dialogElement) {
204
222
  if (this.open) {
@@ -215,11 +233,17 @@ handleOpenStateChange_fn = function() {
215
233
  const popoverElement = __privateGet(this, _popoverElementRef).value;
216
234
  if (popoverElement) {
217
235
  if (this.open) {
236
+ this._isClosing = false;
218
237
  __privateMethod(this, _AiDialogComponent_instances, addEscapeKeyListener_fn).call(this);
219
238
  popoverElement.showPopover();
220
239
  } else {
221
240
  __privateMethod(this, _AiDialogComponent_instances, removeEscapeKeyListener_fn).call(this);
222
- popoverElement.hidePopover();
241
+ this._isClosing = true;
242
+ __privateSet(this, _closeTimeout, window.setTimeout(() => {
243
+ this._isClosing = false;
244
+ popoverElement.hidePopover();
245
+ __privateSet(this, _closeTimeout, void 0);
246
+ }, CLOSE_ANIMATION_DURATION));
223
247
  }
224
248
  }
225
249
  }
@@ -261,6 +285,9 @@ __decorateClass([
261
285
  __decorateClass([
262
286
  state()
263
287
  ], AiDialogComponent.prototype, "_isFullscreen", 2);
288
+ __decorateClass([
289
+ state()
290
+ ], AiDialogComponent.prototype, "_isClosing", 2);
264
291
  AiDialogComponent = __decorateClass([
265
292
  customElement(AiDialogComponentTagName)
266
293
  ], AiDialogComponent);
@@ -1,4 +1,4 @@
1
- const styles = '/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/* prettier-ignore */\n.forge-icon-button {\n --_icon-button-display: var(--forge-icon-button-display, inline-flex);\n --_icon-button-size: var(--forge-icon-button-size, 48px);\n --_icon-button-gap: var(--forge-icon-button-gap, 0);\n --_icon-button-icon-color: var(--forge-icon-button-icon-color, currentColor);\n --_icon-button-background-color: var(--forge-icon-button-background-color, none);\n --_icon-button-icon-size: var(--forge-icon-button-icon-size, calc(var(--forge-typography-font-size, 1rem) * 1.5));\n --_icon-button-cursor: var(--forge-icon-button-cursor, pointer);\n --_icon-button-padding: var(--forge-icon-button-padding, var(--forge-spacing-xxsmall, 4px));\n --_icon-button-border: var(--forge-icon-button-border, none);\n --_icon-button-shadow: var(--forge-icon-button-shadow, none);\n --_icon-button-transition-duration: var(--forge-icon-button-transition-duration, var(--forge-animation-duration-short3, 150ms));\n --_icon-button-transition-timing: var(--forge-icon-button-transition-timing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));\n --_icon-button-shape: var(--forge-icon-button-shape, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n --_icon-button-shape-start-start: var(--forge-icon-button-shape-start-start, var(--_icon-button-shape));\n --_icon-button-shape-start-end: var(--forge-icon-button-shape-start-end, var(--_icon-button-shape));\n --_icon-button-shape-end-start: var(--forge-icon-button-shape-end-start, var(--_icon-button-shape));\n --_icon-button-shape-end-end: var(--forge-icon-button-shape-end-end, var(--_icon-button-shape));\n --_icon-button-shape-squared: var(--forge-icon-button-shape-squared, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_icon-button-outlined-border-width: var(--forge-icon-button-outlined-border-width, 1px);\n --_icon-button-outlined-border-style: var(--forge-icon-button-outlined-border-style, solid);\n --_icon-button-outlined-border-color: var(--forge-icon-button-outlined-border-color, var(--_icon-button-icon-color));\n --_icon-button-tonal-icon-color: var(--forge-icon-button-tonal-icon-color, var(--forge-theme-on-primary-container, #222c62));\n --_icon-button-tonal-background-color: var(--forge-icon-button-tonal-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-filled-icon-color: var(--forge-icon-button-filled-icon-color, var(--forge-theme-on-primary, #ffffff));\n --_icon-button-filled-background-color: var(--forge-icon-button-filled-background-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-raised-shadow: var(--forge-icon-button-raised-shadow, 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-hover-shadow: var(--forge-icon-button-raised-hover-shadow, 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-active-shadow: var(--forge-icon-button-raised-active-shadow, 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-disabled-shadow: var(--forge-icon-button-raised-disabled-shadow, none);\n --_icon-button-density-small-size: var(--forge-icon-button-density-small-size, 24px);\n --_icon-button-density-small-padding: var(--forge-icon-button-density-small-padding, var(--forge-spacing-xxxsmall, 2px));\n --_icon-button-density-small-icon-size: var(--forge-icon-button-density-small-icon-size, calc(var(--forge-typography-font-size, 1rem) * 1.125));\n --_icon-button-density-medium-size: var(--forge-icon-button-density-medium-size, 36px);\n --_icon-button-density-medium-padding: var(--forge-icon-button-density-medium-padding, var(--forge-spacing-xxsmall, 4px));\n --_icon-button-density-large-size: var(--forge-icon-button-density-large-size, var(--_icon-button-size));\n --_icon-button-toggle-on-background-color: var(--forge-icon-button-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-toggle-on-icon-color: var(--forge-icon-button-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-outlined-toggle-on-background-color: var(--forge-icon-button-outlined-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-outlined-toggle-on-icon-color: var(--forge-icon-button-outlined-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-tonal-toggle-background-color: var(--forge-icon-button-tonal-toggle-background-color, var(--forge-theme-surface-container-low, #ebebeb));\n --_icon-button-tonal-toggle-on-background-color: var(--forge-icon-button-tonal-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-tonal-toggle-on-icon-color: var(--forge-icon-button-tonal-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-background-color: var(--forge-icon-button-filled-toggle-background-color, var(--forge-theme-surface-container-low, #ebebeb));\n --_icon-button-filled-toggle-icon-color: var(--forge-icon-button-filled-toggle-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-on-background-color: var(--forge-icon-button-filled-toggle-on-background-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-on-icon-color: var(--forge-icon-button-filled-toggle-on-icon-color, var(--forge-theme-on-primary, #ffffff));\n --_icon-button-disabled-cursor: var(--forge-icon-button-disabled-cursor, not-allowed);\n --_icon-button-disabled-opacity: var(--forge-icon-button-disabled-opacity, 0.38);\n --_icon-button-popover-icon-padding: var(--forge-icon-button-popover-icon-padding, var(--forge-spacing-xsmall, 8px));\n --_icon-button-focus-indicator-color: var(--forge-icon-button-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n}\n\n.forge-icon-button {\n display: var(--_icon-button-display);\n position: relative;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n position: relative;\n z-index: 0;\n display: var(--_icon-button-display);\n align-items: center;\n justify-content: center;\n gap: var(--_icon-button-gap);\n box-sizing: border-box;\n height: var(--_icon-button-density-large-size);\n min-width: var(--_icon-button-density-large-size);\n border: var(--_icon-button-border);\n border-start-start-radius: var(--_icon-button-shape-start-start);\n border-start-end-radius: var(--_icon-button-shape-start-end);\n border-end-start-radius: var(--_icon-button-shape-end-start);\n border-end-end-radius: var(--_icon-button-shape-end-end);\n padding: var(--_icon-button-padding);\n box-shadow: var(--_icon-button-shadow);\n color: var(--_icon-button-icon-color);\n background: var(--_icon-button-background-color);\n font-size: var(--_icon-button-icon-size);\n cursor: var(--_icon-button-cursor);\n user-select: none;\n transition-property: box-shadow, background;\n transition-duration: var(--_icon-button-transition-duration);\n transition-timing-function: var(--_icon-button-transition-timing);\n}\n\n.forge-icon-button img,\n.forge-icon-button svg {\n height: var(--_icon-button-icon-size);\n width: var(--_icon-button-icon-size);\n}\n\n.forge-icon-button svg {\n fill: currentColor;\n}\n\n.forge-icon-button:not(:disabled) {\n --_state-layer-display: var(--forge-state-layer-display, flex);\n --_state-layer-color: var(--forge-state-layer-color, var(--forge-theme-on-surface, #000000));\n --_state-layer-hover-color: var(--forge-state-layer-hover-color, var(--_state-layer-color));\n --_state-layer-hover-opacity: var(--forge-state-layer-hover-opacity, 0.08);\n --_state-layer-pressed-color: var(--forge-state-layer-pressed-color, var(--_state-layer-color));\n --_state-layer-pressed-opacity: var(--forge-state-layer-pressed-opacity, 0.12);\n --_state-layer-hover-duration: var(--forge-state-layer-hover-duration, 15ms);\n --_state-layer-pressed-duration: var(--forge-state-layer-pressed-duration, 105ms);\n --_state-layer-animation-duration: var(--forge-state-layer-animation-duration, 375ms);\n}\n\n.forge-icon-button:not(:disabled)::before {\n opacity: 0;\n position: absolute;\n background-color: var(--_state-layer-hover-color);\n inset: 0;\n transition: opacity var(--_state-layer-hover-duration) linear, background-color var(--_state-layer-hover-duration) linear;\n --_state-layer-hover-duration: var(--forge-state-layer-hover-duration, 100ms);\n content: "";\n opacity: 0;\n border-radius: inherit;\n}\n\n.forge-icon-button:not(:disabled):hover::before {\n background-color: var(--_state-layer-hover-color);\n opacity: var(--_state-layer-hover-opacity);\n}\n\n.forge-icon-button:not(:disabled):active::before {\n opacity: var(--_state-layer-pressed-opacity);\n transition-duration: var(--_state-layer-pressed-duration);\n --_state-layer-pressed-opacity: var(--forge-state-layer-pressed-opacity, 0.18);\n}\n\n.forge-icon-button:not(:disabled) {\n --forge-state-layer-color: var(--_icon-button-icon-color);\n}\n\n@keyframes forge-focus-indicator-outward-grow {\n from {\n outline-width: 0;\n }\n to {\n outline-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-outward-shrink {\n from {\n outline-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-inward-grow {\n from {\n border-width: 0;\n }\n to {\n border-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-inward-shrink {\n from {\n border-width: var(--_focus-indicator-active-width);\n }\n}\n.forge-icon-button:not(:disabled) {\n outline: none;\n}\n\n.forge-icon-button:not(:disabled):focus-visible::after {\n --_focus-indicator-display: var(--forge-focus-indicator-display, flex);\n --_focus-indicator-width: var(--forge-focus-indicator-width, var(--forge-border-medium, 2px));\n --_focus-indicator-active-width: var(--forge-focus-indicator-active-width, 6px);\n --_focus-indicator-color: var(--forge-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n --_focus-indicator-shape: var(--forge-focus-indicator-shape, calc(var(--forge-shape-extra-small, 1px) * var(--forge-shape-factor, 1)));\n --_focus-indicator-duration: var(--forge-focus-indicator-duration, var(--forge-animation-duration-long4, 600ms));\n --_focus-indicator-easing: var(--forge-focus-indicator-easing, var(--forge-animation-easing-emphasized, cubic-bezier(0.2, 0, 0, 1)));\n --_focus-indicator-shape-start-start: var(--forge-focus-indicator-shape-start-start, var(--_focus-indicator-shape));\n --_focus-indicator-shape-start-end: var(--forge-focus-indicator-shape-start-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-end: var(--forge-focus-indicator-shape-end-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-start: var(--forge-focus-indicator-shape-end-start, var(--_focus-indicator-shape));\n --_focus-indicator-outward-offset: var(--forge-focus-indicator-outward-offset, var(--forge-spacing-xxsmall, 4px));\n --_focus-indicator-inward-offset: var(--forge-focus-indicator-inward-offset, 0px);\n --_focus-indicator-offset-block: var(--forge-focus-indicator-offset-block, 0);\n --_focus-indicator-offset-inline: var(--forge-focus-indicator-offset-inline, 0);\n}\n\n.forge-icon-button:not(:disabled):focus-visible::after {\n animation-delay: 0s, calc(var(--_focus-indicator-duration) * 0.25);\n animation-duration: calc(var(--_focus-indicator-duration) * 0.25), calc(var(--_focus-indicator-duration) * 0.75);\n animation-timing-function: var(--_focus-indicator-easing);\n box-sizing: border-box;\n color: var(--_focus-indicator-color);\n display: none;\n pointer-events: none;\n position: absolute;\n margin-block: var(--_focus-indicator-offset-block);\n margin-inline: var(--_focus-indicator-offset-inline);\n animation-name: forge-focus-indicator-outward-grow, forge-focus-indicator-outward-shrink;\n border-end-end-radius: calc(var(--_focus-indicator-shape-end-end) + var(--_focus-indicator-outward-offset));\n border-end-start-radius: calc(var(--_focus-indicator-shape-end-start) + var(--_focus-indicator-outward-offset));\n border-start-end-radius: calc(var(--_focus-indicator-shape-start-end) + var(--_focus-indicator-outward-offset));\n border-start-start-radius: calc(var(--_focus-indicator-shape-start-start) + var(--_focus-indicator-outward-offset));\n inset: calc(-1 * var(--_focus-indicator-outward-offset));\n outline: var(--_focus-indicator-width) solid currentColor;\n content: "";\n display: block;\n}\n\n.forge-icon-button:not(:disabled) {\n --forge-focus-indicator-color: var(--_icon-button-focus-indicator-color);\n --forge-focus-indicator-shape: var(--_icon-button-shape);\n}\n\n.forge-icon-button:not(:disabled):where(.forge-icon-button--text,\n:not(:where(.forge-icon-button--outlined, .forge-icon-button--tonal, .forge-icon-button--filled, .forge-icon-button--raised))) {\n --forge-focus-indicator-outward-offset: 0px;\n}\n\n.forge-icon-button--outlined {\n border-width: var(--_icon-button-outlined-border-width);\n border-style: var(--_icon-button-outlined-border-style);\n border-color: var(--_icon-button-outlined-border-color);\n}\n\n.forge-icon-button--tonal {\n --_icon-button-icon-color: var(--_icon-button-tonal-icon-color);\n --_icon-button-background-color: var(--_icon-button-tonal-background-color);\n}\n\n.forge-icon-button--filled, .forge-icon-button--raised {\n --_icon-button-icon-color: var(--_icon-button-filled-icon-color);\n --_icon-button-background-color: var(--_icon-button-filled-background-color);\n}\n\n.forge-icon-button--raised {\n --_icon-button-shadow: var(--_icon-button-raised-shadow);\n}\n\n.forge-icon-button--raised:hover {\n --_icon-button-raised-shadow: var(--_icon-button-raised-hover-shadow);\n}\n\n.forge-icon-button--raised:active {\n --_icon-button-raised-shadow: var(--_icon-button-raised-active-shadow);\n}\n\n.forge-icon-button--squared {\n --_icon-button-shape: var(--_icon-button-shape-squared);\n}\n\n.forge-icon-button--small {\n --_icon-button-size: var(--_icon-button-density-small-size);\n --_icon-button-icon-size: var(--_icon-button-density-small-icon-size);\n --_icon-button-padding: var(--_icon-button-density-small-padding);\n}\n\n.forge-icon-button--small > * {\n font-size: var(--_icon-button-density-small-icon-size);\n}\n\n.forge-icon-button--medium {\n --_icon-button-size: var(--_icon-button-density-medium-size);\n --_icon-button-padding: var(--_icon-button-density-medium-padding);\n}\n\n.forge-icon-button:disabled {\n pointer-events: none;\n opacity: var(--_icon-button-disabled-opacity);\n pointer-events: auto;\n cursor: not-allowed;\n}\n\n.forge-icon-button forge-circular-progress {\n --forge-circular-progress-indicator-color: var(--_icon-button-icon-color);\n --forge-circular-progress-track-color: transparent;\n --forge-circular-progress-size: 1em;\n}\n\n.ai-icon-button > svg {\n fill: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n}\n\n:host {\n display: contents;\n}\n\nforge-ai-chat-interface {\n flex-grow: 1;\n}\n\n.ai-dialog {\n position: relative;\n overflow: hidden;\n box-sizing: border-box;\n background: var(--forge-theme-surface-bright, #ffffff);\n border-radius: calc(var(--forge-shape-large, 8px) * var(--forge-shape-factor, 1));\n box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12);\n border: none;\n width: 420px;\n height: calc(100vh - 72px);\n padding: 0;\n inset: auto;\n bottom: var(--forge-spacing-medium, 16px);\n right: var(--forge-spacing-medium, 16px);\n animation-duration: 150ms;\n animation-timing-function: cubic-bezier(0, 0, 0, 1);\n animation-name: fadein, zoomin;\n transform-origin: right bottom;\n}\n\n@keyframes fadein {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes zoomin {\n from {\n transform: scale(0.8);\n }\n to {\n transform: scale(1);\n }\n}\n.drag-handle {\n position: absolute;\n top: var(--forge-spacing-xxsmall, 4px);\n left: 50%;\n transform: translateX(-50%);\n z-index: 10;\n opacity: 0;\n visibility: hidden;\n transition: opacity 150ms ease, visibility 150ms ease;\n cursor: grab;\n}\n.drag-handle:active {\n cursor: grabbing;\n}\n\n.ai-dialog:hover .drag-handle,\n.ai-dialog:focus-within .drag-handle {\n opacity: 1;\n visibility: visible;\n}\n\n.ai-dialog.dragging {\n opacity: 0.7;\n transition: none;\n}';
1
+ const styles = '/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/**\n * @license\n * Copyright Tyler Technologies, Inc. \n * License: Apache-2.0\n */\n/* prettier-ignore */\n.forge-icon-button {\n --_icon-button-display: var(--forge-icon-button-display, inline-flex);\n --_icon-button-size: var(--forge-icon-button-size, 48px);\n --_icon-button-gap: var(--forge-icon-button-gap, 0);\n --_icon-button-icon-color: var(--forge-icon-button-icon-color, currentColor);\n --_icon-button-background-color: var(--forge-icon-button-background-color, none);\n --_icon-button-icon-size: var(--forge-icon-button-icon-size, calc(var(--forge-typography-font-size, 1rem) * 1.5));\n --_icon-button-cursor: var(--forge-icon-button-cursor, pointer);\n --_icon-button-padding: var(--forge-icon-button-padding, var(--forge-spacing-xxsmall, 4px));\n --_icon-button-border: var(--forge-icon-button-border, none);\n --_icon-button-shadow: var(--forge-icon-button-shadow, none);\n --_icon-button-transition-duration: var(--forge-icon-button-transition-duration, var(--forge-animation-duration-short3, 150ms));\n --_icon-button-transition-timing: var(--forge-icon-button-transition-timing, var(--forge-animation-easing-standard, cubic-bezier(0.2, 0, 0, 1)));\n --_icon-button-shape: var(--forge-icon-button-shape, calc(var(--forge-shape-full, 9999px) * var(--forge-shape-factor, 1)));\n --_icon-button-shape-start-start: var(--forge-icon-button-shape-start-start, var(--_icon-button-shape));\n --_icon-button-shape-start-end: var(--forge-icon-button-shape-start-end, var(--_icon-button-shape));\n --_icon-button-shape-end-start: var(--forge-icon-button-shape-end-start, var(--_icon-button-shape));\n --_icon-button-shape-end-end: var(--forge-icon-button-shape-end-end, var(--_icon-button-shape));\n --_icon-button-shape-squared: var(--forge-icon-button-shape-squared, calc(var(--forge-shape-medium, 4px) * var(--forge-shape-factor, 1)));\n --_icon-button-outlined-border-width: var(--forge-icon-button-outlined-border-width, 1px);\n --_icon-button-outlined-border-style: var(--forge-icon-button-outlined-border-style, solid);\n --_icon-button-outlined-border-color: var(--forge-icon-button-outlined-border-color, var(--_icon-button-icon-color));\n --_icon-button-tonal-icon-color: var(--forge-icon-button-tonal-icon-color, var(--forge-theme-on-primary-container, #222c62));\n --_icon-button-tonal-background-color: var(--forge-icon-button-tonal-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-filled-icon-color: var(--forge-icon-button-filled-icon-color, var(--forge-theme-on-primary, #ffffff));\n --_icon-button-filled-background-color: var(--forge-icon-button-filled-background-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-raised-shadow: var(--forge-icon-button-raised-shadow, 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-hover-shadow: var(--forge-icon-button-raised-hover-shadow, 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-active-shadow: var(--forge-icon-button-raised-active-shadow, 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12));\n --_icon-button-raised-disabled-shadow: var(--forge-icon-button-raised-disabled-shadow, none);\n --_icon-button-density-small-size: var(--forge-icon-button-density-small-size, 24px);\n --_icon-button-density-small-padding: var(--forge-icon-button-density-small-padding, var(--forge-spacing-xxxsmall, 2px));\n --_icon-button-density-small-icon-size: var(--forge-icon-button-density-small-icon-size, calc(var(--forge-typography-font-size, 1rem) * 1.125));\n --_icon-button-density-medium-size: var(--forge-icon-button-density-medium-size, 36px);\n --_icon-button-density-medium-padding: var(--forge-icon-button-density-medium-padding, var(--forge-spacing-xxsmall, 4px));\n --_icon-button-density-large-size: var(--forge-icon-button-density-large-size, var(--_icon-button-size));\n --_icon-button-toggle-on-background-color: var(--forge-icon-button-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-toggle-on-icon-color: var(--forge-icon-button-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-outlined-toggle-on-background-color: var(--forge-icon-button-outlined-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-outlined-toggle-on-icon-color: var(--forge-icon-button-outlined-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-tonal-toggle-background-color: var(--forge-icon-button-tonal-toggle-background-color, var(--forge-theme-surface-container-low, #ebebeb));\n --_icon-button-tonal-toggle-on-background-color: var(--forge-icon-button-tonal-toggle-on-background-color, var(--forge-theme-primary-container, #d1d5ed));\n --_icon-button-tonal-toggle-on-icon-color: var(--forge-icon-button-tonal-toggle-on-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-background-color: var(--forge-icon-button-filled-toggle-background-color, var(--forge-theme-surface-container-low, #ebebeb));\n --_icon-button-filled-toggle-icon-color: var(--forge-icon-button-filled-toggle-icon-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-on-background-color: var(--forge-icon-button-filled-toggle-on-background-color, var(--forge-theme-primary, #3f51b5));\n --_icon-button-filled-toggle-on-icon-color: var(--forge-icon-button-filled-toggle-on-icon-color, var(--forge-theme-on-primary, #ffffff));\n --_icon-button-disabled-cursor: var(--forge-icon-button-disabled-cursor, not-allowed);\n --_icon-button-disabled-opacity: var(--forge-icon-button-disabled-opacity, 0.38);\n --_icon-button-popover-icon-padding: var(--forge-icon-button-popover-icon-padding, var(--forge-spacing-xsmall, 8px));\n --_icon-button-focus-indicator-color: var(--forge-icon-button-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n}\n\n.forge-icon-button {\n display: var(--_icon-button-display);\n position: relative;\n outline: none;\n -webkit-tap-highlight-color: transparent;\n position: relative;\n z-index: 0;\n display: var(--_icon-button-display);\n align-items: center;\n justify-content: center;\n gap: var(--_icon-button-gap);\n box-sizing: border-box;\n height: var(--_icon-button-density-large-size);\n min-width: var(--_icon-button-density-large-size);\n border: var(--_icon-button-border);\n border-start-start-radius: var(--_icon-button-shape-start-start);\n border-start-end-radius: var(--_icon-button-shape-start-end);\n border-end-start-radius: var(--_icon-button-shape-end-start);\n border-end-end-radius: var(--_icon-button-shape-end-end);\n padding: var(--_icon-button-padding);\n box-shadow: var(--_icon-button-shadow);\n color: var(--_icon-button-icon-color);\n background: var(--_icon-button-background-color);\n font-size: var(--_icon-button-icon-size);\n cursor: var(--_icon-button-cursor);\n user-select: none;\n transition-property: box-shadow, background;\n transition-duration: var(--_icon-button-transition-duration);\n transition-timing-function: var(--_icon-button-transition-timing);\n}\n\n.forge-icon-button img,\n.forge-icon-button svg {\n height: var(--_icon-button-icon-size);\n width: var(--_icon-button-icon-size);\n}\n\n.forge-icon-button svg {\n fill: currentColor;\n}\n\n.forge-icon-button:not(:disabled) {\n --_state-layer-display: var(--forge-state-layer-display, flex);\n --_state-layer-color: var(--forge-state-layer-color, var(--forge-theme-on-surface, #000000));\n --_state-layer-hover-color: var(--forge-state-layer-hover-color, var(--_state-layer-color));\n --_state-layer-hover-opacity: var(--forge-state-layer-hover-opacity, 0.08);\n --_state-layer-pressed-color: var(--forge-state-layer-pressed-color, var(--_state-layer-color));\n --_state-layer-pressed-opacity: var(--forge-state-layer-pressed-opacity, 0.12);\n --_state-layer-hover-duration: var(--forge-state-layer-hover-duration, 15ms);\n --_state-layer-pressed-duration: var(--forge-state-layer-pressed-duration, 105ms);\n --_state-layer-animation-duration: var(--forge-state-layer-animation-duration, 375ms);\n}\n\n.forge-icon-button:not(:disabled)::before {\n opacity: 0;\n position: absolute;\n background-color: var(--_state-layer-hover-color);\n inset: 0;\n transition: opacity var(--_state-layer-hover-duration) linear, background-color var(--_state-layer-hover-duration) linear;\n --_state-layer-hover-duration: var(--forge-state-layer-hover-duration, 100ms);\n content: "";\n opacity: 0;\n border-radius: inherit;\n}\n\n.forge-icon-button:not(:disabled):hover::before {\n background-color: var(--_state-layer-hover-color);\n opacity: var(--_state-layer-hover-opacity);\n}\n\n.forge-icon-button:not(:disabled):active::before {\n opacity: var(--_state-layer-pressed-opacity);\n transition-duration: var(--_state-layer-pressed-duration);\n --_state-layer-pressed-opacity: var(--forge-state-layer-pressed-opacity, 0.18);\n}\n\n.forge-icon-button:not(:disabled) {\n --forge-state-layer-color: var(--_icon-button-icon-color);\n}\n\n@keyframes forge-focus-indicator-outward-grow {\n from {\n outline-width: 0;\n }\n to {\n outline-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-outward-shrink {\n from {\n outline-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-inward-grow {\n from {\n border-width: 0;\n }\n to {\n border-width: var(--_focus-indicator-active-width);\n }\n}\n@keyframes forge-focus-indicator-inward-shrink {\n from {\n border-width: var(--_focus-indicator-active-width);\n }\n}\n.forge-icon-button:not(:disabled) {\n outline: none;\n}\n\n.forge-icon-button:not(:disabled):focus-visible::after {\n --_focus-indicator-display: var(--forge-focus-indicator-display, flex);\n --_focus-indicator-width: var(--forge-focus-indicator-width, var(--forge-border-medium, 2px));\n --_focus-indicator-active-width: var(--forge-focus-indicator-active-width, 6px);\n --_focus-indicator-color: var(--forge-focus-indicator-color, var(--forge-theme-primary, #3f51b5));\n --_focus-indicator-shape: var(--forge-focus-indicator-shape, calc(var(--forge-shape-extra-small, 1px) * var(--forge-shape-factor, 1)));\n --_focus-indicator-duration: var(--forge-focus-indicator-duration, var(--forge-animation-duration-long4, 600ms));\n --_focus-indicator-easing: var(--forge-focus-indicator-easing, var(--forge-animation-easing-emphasized, cubic-bezier(0.2, 0, 0, 1)));\n --_focus-indicator-shape-start-start: var(--forge-focus-indicator-shape-start-start, var(--_focus-indicator-shape));\n --_focus-indicator-shape-start-end: var(--forge-focus-indicator-shape-start-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-end: var(--forge-focus-indicator-shape-end-end, var(--_focus-indicator-shape));\n --_focus-indicator-shape-end-start: var(--forge-focus-indicator-shape-end-start, var(--_focus-indicator-shape));\n --_focus-indicator-outward-offset: var(--forge-focus-indicator-outward-offset, var(--forge-spacing-xxsmall, 4px));\n --_focus-indicator-inward-offset: var(--forge-focus-indicator-inward-offset, 0px);\n --_focus-indicator-offset-block: var(--forge-focus-indicator-offset-block, 0);\n --_focus-indicator-offset-inline: var(--forge-focus-indicator-offset-inline, 0);\n}\n\n.forge-icon-button:not(:disabled):focus-visible::after {\n animation-delay: 0s, calc(var(--_focus-indicator-duration) * 0.25);\n animation-duration: calc(var(--_focus-indicator-duration) * 0.25), calc(var(--_focus-indicator-duration) * 0.75);\n animation-timing-function: var(--_focus-indicator-easing);\n box-sizing: border-box;\n color: var(--_focus-indicator-color);\n display: none;\n pointer-events: none;\n position: absolute;\n margin-block: var(--_focus-indicator-offset-block);\n margin-inline: var(--_focus-indicator-offset-inline);\n animation-name: forge-focus-indicator-outward-grow, forge-focus-indicator-outward-shrink;\n border-end-end-radius: calc(var(--_focus-indicator-shape-end-end) + var(--_focus-indicator-outward-offset));\n border-end-start-radius: calc(var(--_focus-indicator-shape-end-start) + var(--_focus-indicator-outward-offset));\n border-start-end-radius: calc(var(--_focus-indicator-shape-start-end) + var(--_focus-indicator-outward-offset));\n border-start-start-radius: calc(var(--_focus-indicator-shape-start-start) + var(--_focus-indicator-outward-offset));\n inset: calc(-1 * var(--_focus-indicator-outward-offset));\n outline: var(--_focus-indicator-width) solid currentColor;\n content: "";\n display: block;\n}\n\n.forge-icon-button:not(:disabled) {\n --forge-focus-indicator-color: var(--_icon-button-focus-indicator-color);\n --forge-focus-indicator-shape: var(--_icon-button-shape);\n}\n\n.forge-icon-button:not(:disabled):where(.forge-icon-button--text,\n:not(:where(.forge-icon-button--outlined, .forge-icon-button--tonal, .forge-icon-button--filled, .forge-icon-button--raised))) {\n --forge-focus-indicator-outward-offset: 0px;\n}\n\n.forge-icon-button--outlined {\n border-width: var(--_icon-button-outlined-border-width);\n border-style: var(--_icon-button-outlined-border-style);\n border-color: var(--_icon-button-outlined-border-color);\n}\n\n.forge-icon-button--tonal {\n --_icon-button-icon-color: var(--_icon-button-tonal-icon-color);\n --_icon-button-background-color: var(--_icon-button-tonal-background-color);\n}\n\n.forge-icon-button--filled, .forge-icon-button--raised {\n --_icon-button-icon-color: var(--_icon-button-filled-icon-color);\n --_icon-button-background-color: var(--_icon-button-filled-background-color);\n}\n\n.forge-icon-button--raised {\n --_icon-button-shadow: var(--_icon-button-raised-shadow);\n}\n\n.forge-icon-button--raised:hover {\n --_icon-button-raised-shadow: var(--_icon-button-raised-hover-shadow);\n}\n\n.forge-icon-button--raised:active {\n --_icon-button-raised-shadow: var(--_icon-button-raised-active-shadow);\n}\n\n.forge-icon-button--squared {\n --_icon-button-shape: var(--_icon-button-shape-squared);\n}\n\n.forge-icon-button--small {\n --_icon-button-size: var(--_icon-button-density-small-size);\n --_icon-button-icon-size: var(--_icon-button-density-small-icon-size);\n --_icon-button-padding: var(--_icon-button-density-small-padding);\n}\n\n.forge-icon-button--small > * {\n font-size: var(--_icon-button-density-small-icon-size);\n}\n\n.forge-icon-button--medium {\n --_icon-button-size: var(--_icon-button-density-medium-size);\n --_icon-button-padding: var(--_icon-button-density-medium-padding);\n}\n\n.forge-icon-button:disabled {\n pointer-events: none;\n opacity: var(--_icon-button-disabled-opacity);\n pointer-events: auto;\n cursor: not-allowed;\n}\n\n.forge-icon-button forge-circular-progress {\n --forge-circular-progress-indicator-color: var(--_icon-button-icon-color);\n --forge-circular-progress-track-color: transparent;\n --forge-circular-progress-size: 1em;\n}\n\n.ai-icon-button > svg {\n fill: var(--forge-theme-text-medium, rgba(0, 0, 0, 0.6));\n}\n\n:host {\n display: contents;\n}\n\nforge-ai-chat-interface {\n flex-grow: 1;\n}\n\n.ai-dialog {\n position: relative;\n overflow: hidden;\n box-sizing: border-box;\n background: var(--forge-theme-surface-bright, #ffffff);\n border-radius: calc(var(--forge-shape-large, 8px) * var(--forge-shape-factor, 1));\n box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12);\n border: none;\n outline: none;\n width: 420px;\n height: calc(100vh - 72px);\n padding: 0;\n inset: auto;\n bottom: var(--forge-spacing-medium, 16px);\n right: var(--forge-spacing-medium, 16px);\n animation-duration: 150ms;\n animation-timing-function: cubic-bezier(0, 0, 0, 1);\n animation-name: fadein, zoomin;\n transform-origin: right bottom;\n}\n.ai-dialog:popover-open::backdrop {\n display: none;\n}\n.ai-dialog.closing {\n animation-duration: 100ms;\n animation-timing-function: cubic-bezier(0.3, 0, 1, 1);\n animation-name: fadeout, zoomout;\n animation-fill-mode: forwards;\n transform-origin: right bottom;\n}\n\n@keyframes fadein {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes zoomin {\n from {\n transform: scale(0.8);\n }\n to {\n transform: scale(1);\n }\n}\n@keyframes fadeout {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n}\n@keyframes zoomout {\n from {\n transform: scale(1);\n }\n to {\n transform: scale(0.8);\n }\n}\n.drag-handle {\n position: absolute;\n top: var(--forge-spacing-xxsmall, 4px);\n left: 50%;\n transform: translateX(-50%);\n z-index: 10;\n opacity: 0;\n visibility: hidden;\n transition: opacity 150ms ease, visibility 150ms ease;\n cursor: grab;\n}\n.drag-handle:active {\n cursor: grabbing;\n}\n\n.ai-dialog:hover .drag-handle,\n.ai-dialog:focus-within .drag-handle {\n opacity: 1;\n visibility: visible;\n}\n\n.ai-dialog.dragging {\n opacity: 0.7;\n transition: none;\n}';
2
2
  export {
3
3
  styles as default
4
4
  };
@@ -108,7 +108,6 @@ export declare class ForgeAiDropdownMenuComponent extends LitElement {
108
108
  * For none mode: null
109
109
  */
110
110
  value: string | string[] | null;
111
- private _triggerButtonId;
112
111
  private _isSubmenu;
113
112
  private _navigationController;
114
113
  private _selectionManager;
@@ -2,7 +2,6 @@ import { unsafeCSS, LitElement, html } from "lit";
2
2
  import { property, state, query, queryAssignedElements, customElement } from "lit/decorators.js";
3
3
  import { classMap } from "lit/directives/class-map.js";
4
4
  import { ifDefined } from "lit/directives/if-defined.js";
5
- import { generateUniqueId } from "../utils.mjs";
6
5
  import { DropdownNavigationController } from "./navigation-controller.mjs";
7
6
  import { SelectionManager } from "./selection-manager.mjs";
8
7
  import styles from "./ai-dropdown-menu.scss.mjs";
@@ -37,7 +36,6 @@ let ForgeAiDropdownMenuComponent = class extends LitElement {
37
36
  this.disabled = false;
38
37
  this.selectionMode = "none";
39
38
  this.value = null;
40
- this._triggerButtonId = generateUniqueId("dropdown-trigger");
41
39
  this._isSubmenu = false;
42
40
  this._onKeyDown = (event) => {
43
41
  if (this.disabled || !this._navigationController) {
@@ -252,7 +250,7 @@ _dropdownContentTemplate = /* @__PURE__ */ new WeakMap();
252
250
  triggerButton_get = function() {
253
251
  return html`
254
252
  <button
255
- id=${this._triggerButtonId}
253
+ id="dropdown-trigger"
256
254
  class=${classMap({
257
255
  "forge-button": this.variant === "button",
258
256
  "forge-icon-button": this.variant === "icon-button"
@@ -260,6 +258,7 @@ triggerButton_get = function() {
260
258
  type="button"
261
259
  aria-expanded=${this.open}
262
260
  aria-haspopup=${this._ariaHasPopup}
261
+ aria-controls="dropdown-content"
263
262
  ?disabled=${this.disabled}
264
263
  @click=${this._handleTriggerClick}>
265
264
  <slot name="start"></slot>
@@ -276,9 +275,11 @@ popoverTemplate_get = function() {
276
275
  .flip=${true}
277
276
  @ai-popover-toggle=${this._onPopoverToggle}>
278
277
  <div
278
+ id="dropdown-content"
279
279
  role=${this._dropdownRole}
280
- aria-labelledby=${this._triggerButtonId}
280
+ aria-labelledby="dropdown-trigger"
281
281
  aria-multiselectable=${ifDefined(this._ariaMultiSelectable)}
282
+ aria-orientation="vertical"
282
283
  @click=${this._onItemClick}
283
284
  tabindex="0"
284
285
  class="ai-dropdown-menu__dropdown"
@@ -304,9 +305,6 @@ __decorateClass([
304
305
  __decorateClass([
305
306
  property()
306
307
  ], ForgeAiDropdownMenuComponent.prototype, "value", 2);
307
- __decorateClass([
308
- state()
309
- ], ForgeAiDropdownMenuComponent.prototype, "_triggerButtonId", 2);
310
308
  __decorateClass([
311
309
  state()
312
310
  ], ForgeAiDropdownMenuComponent.prototype, "_isSubmenu", 2);
@@ -1,16 +1,16 @@
1
1
  import { LitElement, TemplateResult } from 'lit';
2
2
  declare global {
3
3
  interface HTMLElementTagNameMap {
4
- 'forge-ai-file-picker': ForgeAiFilePickerComponent;
4
+ 'forge-ai-file-picker': AiFilePickerComponent;
5
5
  }
6
6
  interface HTMLElementEventMap {
7
- 'forge-ai-file-picker-change': CustomEvent<AiFilePickerChangeEventData>;
7
+ 'forge-ai-file-picker-change': CustomEvent<ForgeAiFilePickerChangeEventData>;
8
8
  }
9
9
  }
10
10
  /**
11
11
  * Event data interface for the file picker change event.
12
12
  */
13
- export interface AiFilePickerChangeEventData {
13
+ export interface ForgeAiFilePickerChangeEventData {
14
14
  /** The selected file */
15
15
  file: File;
16
16
  /** Timestamp when the file was selected */
@@ -40,10 +40,10 @@ export type AiFilePickerVariant = 'button' | 'icon-button';
40
40
  * @slot - The default slot for button content when no file is selected.
41
41
  * @slot icon - The icon slot for icon-button variant.
42
42
  *
43
- * @event {CustomEvent<AiFilePickerChangeEventData>} forge-ai-file-picker-change - Fired when a file is selected via click or drag & drop.
43
+ * @event {CustomEvent<ForgeAiFilePickerChangeEventData>} forge-ai-file-picker-change - Fired when a file is selected via click or drag & drop.
44
44
  * The event detail contains the selected file and timestamp.
45
45
  */
46
- export declare class ForgeAiFilePickerComponent extends LitElement {
46
+ export declare class AiFilePickerComponent extends LitElement {
47
47
  #private;
48
48
  static styles: import('lit').CSSResult;
49
49
  /**
@@ -19,11 +19,11 @@ var __decorateClass = (decorators, target, key, kind) => {
19
19
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
20
20
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
21
21
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
22
- var _ForgeAiFilePickerComponent_instances, buttonContent_get, fileInput_get, button_get;
23
- let ForgeAiFilePickerComponent = class extends LitElement {
22
+ var _AiFilePickerComponent_instances, buttonContent_get, fileInput_get, button_get;
23
+ let AiFilePickerComponent = class extends LitElement {
24
24
  constructor() {
25
25
  super(...arguments);
26
- __privateAdd(this, _ForgeAiFilePickerComponent_instances);
26
+ __privateAdd(this, _AiFilePickerComponent_instances);
27
27
  this.variant = "icon-button";
28
28
  this.disabled = false;
29
29
  this.accept = "";
@@ -102,10 +102,10 @@ let ForgeAiFilePickerComponent = class extends LitElement {
102
102
  );
103
103
  }
104
104
  render() {
105
- return html` <div class="ai-file-picker">${__privateGet(this, _ForgeAiFilePickerComponent_instances, fileInput_get)} ${__privateGet(this, _ForgeAiFilePickerComponent_instances, button_get)}</div> `;
105
+ return html` <div class="ai-file-picker">${__privateGet(this, _AiFilePickerComponent_instances, fileInput_get)} ${__privateGet(this, _AiFilePickerComponent_instances, button_get)}</div> `;
106
106
  }
107
107
  };
108
- _ForgeAiFilePickerComponent_instances = /* @__PURE__ */ new WeakSet();
108
+ _AiFilePickerComponent_instances = /* @__PURE__ */ new WeakSet();
109
109
  buttonContent_get = function() {
110
110
  if (this.variant === "icon-button") {
111
111
  return html`<slot name="icon">
@@ -142,32 +142,32 @@ button_get = function() {
142
142
  ?disabled=${this.disabled}
143
143
  @click=${this._handleButtonClick}
144
144
  aria-label="Select file to upload">
145
- ${__privateGet(this, _ForgeAiFilePickerComponent_instances, buttonContent_get)}
145
+ ${__privateGet(this, _AiFilePickerComponent_instances, buttonContent_get)}
146
146
  </button>
147
147
  `;
148
148
  };
149
- ForgeAiFilePickerComponent.styles = unsafeCSS(styles);
149
+ AiFilePickerComponent.styles = unsafeCSS(styles);
150
150
  __decorateClass([
151
151
  property()
152
- ], ForgeAiFilePickerComponent.prototype, "variant", 2);
152
+ ], AiFilePickerComponent.prototype, "variant", 2);
153
153
  __decorateClass([
154
154
  property({ type: Boolean, reflect: true })
155
- ], ForgeAiFilePickerComponent.prototype, "disabled", 2);
155
+ ], AiFilePickerComponent.prototype, "disabled", 2);
156
156
  __decorateClass([
157
157
  property()
158
- ], ForgeAiFilePickerComponent.prototype, "accept", 2);
158
+ ], AiFilePickerComponent.prototype, "accept", 2);
159
159
  __decorateClass([
160
160
  property({ type: Boolean })
161
- ], ForgeAiFilePickerComponent.prototype, "multiple", 2);
161
+ ], AiFilePickerComponent.prototype, "multiple", 2);
162
162
  __decorateClass([
163
163
  state()
164
- ], ForgeAiFilePickerComponent.prototype, "_isDragOver", 2);
164
+ ], AiFilePickerComponent.prototype, "_isDragOver", 2);
165
165
  __decorateClass([
166
166
  query('input[type="file"]')
167
- ], ForgeAiFilePickerComponent.prototype, "_fileInput", 2);
168
- ForgeAiFilePickerComponent = __decorateClass([
167
+ ], AiFilePickerComponent.prototype, "_fileInput", 2);
168
+ AiFilePickerComponent = __decorateClass([
169
169
  customElement("forge-ai-file-picker")
170
- ], ForgeAiFilePickerComponent);
170
+ ], AiFilePickerComponent);
171
171
  export {
172
- ForgeAiFilePickerComponent
172
+ AiFilePickerComponent
173
173
  };
@@ -1 +1 @@
1
- export { ForgeAiFilePickerComponent, type AiFilePickerVariant, type AiFilePickerChangeEventData } from './ai-file-picker.js';
1
+ export { AiFilePickerComponent, type AiFilePickerVariant, type ForgeAiFilePickerChangeEventData } from './ai-file-picker.js';
@@ -1,4 +1,4 @@
1
- import { ForgeAiFilePickerComponent } from "./ai-file-picker.mjs";
1
+ import { AiFilePickerComponent } from "./ai-file-picker.mjs";
2
2
  export {
3
- ForgeAiFilePickerComponent
3
+ AiFilePickerComponent
4
4
  };
@@ -4,14 +4,20 @@ declare global {
4
4
  'forge-ai-prompt': AiPromptComponent;
5
5
  }
6
6
  interface HTMLElementEventMap {
7
- 'forge-ai-prompt-send': CustomEvent<AiPromptSendEventData>;
7
+ 'forge-ai-prompt-send': CustomEvent<ForgeAiPromptSendEventData>;
8
+ 'forge-ai-prompt-cancel': CustomEvent<void>;
9
+ 'forge-ai-prompt-attachment': CustomEvent<ForgeAiPromptAttachmentEventData>;
10
+ 'forge-ai-prompt-stop': CustomEvent<void>;
8
11
  }
9
12
  }
10
- export interface AiPromptSendEventData {
13
+ export interface ForgeAiPromptSendEventData {
11
14
  value: string;
12
15
  time: string;
13
16
  date: Date;
14
17
  }
18
+ export interface ForgeAiPromptAttachmentEventData {
19
+ files: File[];
20
+ }
15
21
  export type AiPromptVariant = 'stacked' | 'inline';
16
22
  export declare const AiPromptComponentTagName: keyof HTMLElementTagNameMap;
17
23
  /**
@@ -22,22 +28,44 @@ export declare const AiPromptComponentTagName: keyof HTMLElementTagNameMap;
22
28
  * @state inline - The prompt is in inline layout mode with actions hidden.
23
29
  * @state stacked - The prompt is in stacked layout mode with actions displayed below the input.
24
30
  *
25
- * @event {CustomEvent<AiPromptSendEventData>} forge-ai-prompt-send - Fired when the send button is clicked or Enter is pressed.
31
+ * @event {CustomEvent<ForgeAiPromptSendEventData>} forge-ai-prompt-send - Fired when the send button is clicked or Enter is pressed (without Shift). Cancelable - if cancelled, running state is not set and input is not cleared.
32
+ * @event {CustomEvent<void>} forge-ai-prompt-cancel - Fired when the Escape key is pressed (if cancelOnEscape is true).
33
+ * @event {CustomEvent<ForgeAiPromptAttachmentEventData>} forge-ai-prompt-attachment - Fired when files are pasted into the textarea.
34
+ * @event {CustomEvent<void>} forge-ai-prompt-stop - Fired when the stop button is clicked. Cancelable - if cancelled, running state remains true.
26
35
  */
27
36
  export declare class AiPromptComponent extends LitElement {
28
37
  #private;
29
38
  static styles: import('lit').CSSResult;
30
- /** Placeholder text for the input field */
39
+ /** Placeholder text for the textarea field */
31
40
  placeholder: string;
32
- /** Current value of the input field */
41
+ /** Current value of the textarea field */
33
42
  value: string;
34
43
  /** Layout variant for the prompt component */
35
44
  variant: AiPromptVariant;
45
+ /** Whether the send button is disabled */
46
+ sendDisabled: boolean;
47
+ /** Whether to autofocus the textarea field when the component renders */
48
+ autofocus: boolean;
49
+ /** Whether the textarea field is disabled */
50
+ inputDisabled: boolean;
51
+ /** Whether to dispatch escape events when Escape key is pressed */
52
+ cancelOnEscape: boolean;
53
+ /** Whether the component is in running state (shows stop button instead of send button) */
54
+ running: boolean;
36
55
  private _actionsSlottedNodes;
56
+ private _inputElement;
37
57
  constructor();
38
58
  willUpdate(changedProperties: PropertyValues<this>): void;
59
+ firstUpdated(): void;
39
60
  private _handleSend;
40
61
  private _handleInput;
41
- private _handleKeyPress;
62
+ private _handleKeyDown;
63
+ private _handleStop;
64
+ private _handleEscape;
65
+ private _handlePaste;
66
+ /**
67
+ * Focuses the textarea element
68
+ */
69
+ focus(): void;
42
70
  render(): TemplateResult;
43
71
  }