@tylertech/forge 3.6.0 → 3.6.2

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.
@@ -3,7 +3,7 @@
3
3
  * Copyright Tyler Technologies, Inc.
4
4
  * License: Apache-2.0
5
5
  */
6
- import { getActiveElement, toggleAttribute } from '@tylertech/forge-core';
6
+ import { deepQuerySelectorAll, getActiveElement, toggleAttribute } from '@tylertech/forge-core';
7
7
  import { CHIP_FIELD_CONSTANTS } from '../chip-field';
8
8
  import { BaseAdapter } from '../core/base/base-adapter';
9
9
  import { setAriaControls, tryCreateAriaControlsPlaceholder } from '../core/utils/utils';
@@ -24,7 +24,7 @@ export class AutocompleteAdapter extends BaseAdapter {
24
24
  return this._inputElement;
25
25
  }
26
26
  setInputElement() {
27
- const inputElements = this._component.querySelectorAll(AUTOCOMPLETE_CONSTANTS.selectors.INPUT);
27
+ const inputElements = deepQuerySelectorAll(this._component, AUTOCOMPLETE_CONSTANTS.selectors.INPUT, false);
28
28
  if (inputElements.length) {
29
29
  this._inputElement = inputElements[0];
30
30
  }
@@ -147,3 +147,10 @@ export declare function task(duration?: number): Promise<void>;
147
147
  * Useful for delaying some code until the next animation frame is rendered by the browser.
148
148
  */
149
149
  export declare function frame(): Promise<void>;
150
+ /**
151
+ * Determines if an object is an instance of a specific type.
152
+ * @param obj The object to test.
153
+ * @param name The name of the type to test against.
154
+ * @returns `true` if the object is an instance of the type, otherwise `false`.
155
+ */
156
+ export declare function isInstanceOf<T>(obj: any, name: string): obj is T;
@@ -296,3 +296,12 @@ export function task(duration = 0) {
296
296
  export function frame() {
297
297
  return new Promise(resolve => requestAnimationFrame(() => resolve()));
298
298
  }
299
+ /**
300
+ * Determines if an object is an instance of a specific type.
301
+ * @param obj The object to test.
302
+ * @param name The name of the type to test against.
303
+ * @returns `true` if the object is an instance of the type, otherwise `false`.
304
+ */
305
+ export function isInstanceOf(obj, name) {
306
+ return Object.prototype.toString.call(obj) === `[object ${name}]`;
307
+ }
@@ -10,12 +10,11 @@ export interface IDialogAdapter extends IBaseAdapter<IDialogComponent> {
10
10
  readonly moveHandleElement: HTMLElement;
11
11
  readonly surfaceElement: HTMLElement;
12
12
  triggerElement: HTMLElement | null;
13
+ destroy(): void;
13
14
  show(): void;
14
15
  hide(): Promise<void>;
15
16
  addDialogFormSubmitListener(listener: EventListener): void;
16
17
  removeDialogFormSubmitListener(listener: EventListener): void;
17
- addDialogCancelListener(listener: EventListener): void;
18
- removeDialogCancelListener(listener: EventListener): void;
19
18
  addBackdropDismissListener(listener: EventListener): void;
20
19
  removeBackdropDismissListener(listener: EventListener): void;
21
20
  tryAutofocus(): void;
@@ -43,14 +42,13 @@ export declare class DialogAdapter extends BaseAdapter<IDialogComponent> impleme
43
42
  get moveHandleElement(): HTMLElement;
44
43
  get surfaceElement(): HTMLElement;
45
44
  constructor(component: IDialogComponent);
45
+ destroy(): void;
46
46
  show(): void;
47
47
  private _hideBackdrops;
48
48
  private _showBackdropMostRecent;
49
49
  hide(): Promise<void>;
50
50
  addDialogFormSubmitListener(listener: EventListener): void;
51
51
  removeDialogFormSubmitListener(listener: EventListener): void;
52
- addDialogCancelListener(listener: EventListener): void;
53
- removeDialogCancelListener(listener: EventListener): void;
54
52
  addBackdropDismissListener(listener: EventListener): void;
55
53
  removeBackdropDismissListener(listener: EventListener): void;
56
54
  tryAutofocus(): void;
@@ -65,5 +63,6 @@ export declare class DialogAdapter extends BaseAdapter<IDialogComponent> impleme
65
63
  removeFullscreenListener(listener: (value: boolean) => void): void;
66
64
  setAccessibleLabel(label: string): void;
67
65
  setAccessibleDescription(description: string): void;
68
- private _createVisuallyHiddenElement;
66
+ private _createOrUpdateVisuallyHiddenElement;
67
+ private _forceClose;
69
68
  }
@@ -25,6 +25,9 @@ export class DialogAdapter extends BaseAdapter {
25
25
  window.customElements.upgrade(this._backdropElement);
26
26
  }
27
27
  }
28
+ destroy() {
29
+ this._forceClose();
30
+ }
28
31
  show() {
29
32
  /* c8 ignore next 3 */
30
33
  if (this._dialogElement.open) {
@@ -66,18 +69,13 @@ export class DialogAdapter extends BaseAdapter {
66
69
  .at(-1)?.[showBackdrop]();
67
70
  }
68
71
  async hide() {
69
- const close = () => {
70
- this._surfaceElement.classList.remove(BACKDROP_CONSTANTS.classes.EXITING);
71
- this._dialogElement.close();
72
- DialogComponent[dialogStack].delete(this._component);
73
- this._showBackdropMostRecent();
74
- };
75
72
  if (this._component.animationType === 'none') {
76
- return Promise.resolve(close());
73
+ this._forceClose();
74
+ return Promise.resolve();
77
75
  }
78
76
  this._backdropElement.fadeOut();
79
77
  await playKeyframeAnimation(this._surfaceElement, BACKDROP_CONSTANTS.classes.EXITING);
80
- close();
78
+ this._forceClose();
81
79
  }
82
80
  addDialogFormSubmitListener(listener) {
83
81
  this._dialogElement.addEventListener('submit', listener);
@@ -85,12 +83,6 @@ export class DialogAdapter extends BaseAdapter {
85
83
  removeDialogFormSubmitListener(listener) {
86
84
  this._dialogElement.removeEventListener('submit', listener);
87
85
  }
88
- addDialogCancelListener(listener) {
89
- this._dialogElement.addEventListener('cancel', listener);
90
- }
91
- removeDialogCancelListener(listener) {
92
- this._dialogElement.removeEventListener('cancel', listener);
93
- }
94
86
  addBackdropDismissListener(listener) {
95
87
  this._backdropElement.addEventListener('click', listener);
96
88
  }
@@ -150,31 +142,51 @@ export class DialogAdapter extends BaseAdapter {
150
142
  }
151
143
  setAccessibleLabel(label) {
152
144
  if (label?.trim()) {
153
- this._accessibleLabelElement = this._createVisuallyHiddenElement(DIALOG_CONSTANTS.attributes.ARIA_LABEL_ID, label);
145
+ this._accessibleLabelElement = this._createOrUpdateVisuallyHiddenElement(DIALOG_CONSTANTS.attributes.ARIA_LABEL_ID, label);
146
+ if (this._accessibleLabelElement.isConnected) {
147
+ return;
148
+ }
154
149
  this._dialogElement.appendChild(this._accessibleLabelElement);
155
150
  this._dialogElement.setAttribute('aria-labelledby', this._accessibleLabelElement.id);
156
151
  }
157
- else {
152
+ else if (this._accessibleLabelElement?.isConnected) {
158
153
  this._dialogElement.removeAttribute('aria-labelledby');
159
154
  this._accessibleLabelElement?.remove();
155
+ this._accessibleLabelElement = undefined;
160
156
  }
161
157
  }
162
158
  setAccessibleDescription(description) {
163
159
  if (description?.trim()) {
164
- this._accessibleDescriptionElement = this._createVisuallyHiddenElement(DIALOG_CONSTANTS.attributes.ARIA_DESCIPTION_ID, description);
160
+ this._accessibleDescriptionElement = this._createOrUpdateVisuallyHiddenElement(DIALOG_CONSTANTS.attributes.ARIA_DESCRIPTION_ID, description);
161
+ if (this._accessibleDescriptionElement.isConnected) {
162
+ return;
163
+ }
165
164
  this._dialogElement.appendChild(this._accessibleDescriptionElement);
166
165
  this._dialogElement.setAttribute('aria-describedby', this._accessibleDescriptionElement.id);
167
166
  }
168
- else {
167
+ else if (this._accessibleDescriptionElement?.isConnected) {
169
168
  this._dialogElement.removeAttribute('aria-describedby');
170
169
  this._accessibleDescriptionElement?.remove();
170
+ this._accessibleDescriptionElement = undefined;
171
171
  }
172
172
  }
173
- _createVisuallyHiddenElement(id, text) {
174
- const element = document.createElement('div');
173
+ _createOrUpdateVisuallyHiddenElement(id, text) {
174
+ const content = text.trim();
175
+ let element = this._dialogElement.querySelector(`#${id}`);
176
+ if (element) {
177
+ element.textContent = content;
178
+ return element;
179
+ }
180
+ element = document.createElement('div');
175
181
  element.classList.add('visually-hidden');
176
182
  element.id = id;
177
- element.textContent = text.trim();
183
+ element.textContent = content;
178
184
  return element;
179
185
  }
186
+ _forceClose() {
187
+ this._surfaceElement.classList.remove(BACKDROP_CONSTANTS.classes.EXITING);
188
+ this._dialogElement.close();
189
+ DialogComponent[dialogStack].delete(this._component);
190
+ this._showBackdropMostRecent();
191
+ }
180
192
  }
@@ -30,7 +30,7 @@ export declare const DIALOG_CONSTANTS: {
30
30
  };
31
31
  attributes: {
32
32
  ARIA_LABEL_ID: string;
33
- ARIA_DESCIPTION_ID: string;
33
+ ARIA_DESCRIPTION_ID: string;
34
34
  OPEN: string;
35
35
  VISIBLE: string;
36
36
  MODE: string;
@@ -27,7 +27,7 @@ const observedAttributes = {
27
27
  const attributes = {
28
28
  ...observedAttributes,
29
29
  ARIA_LABEL_ID: 'forge-dialog-label',
30
- ARIA_DESCIPTION_ID: 'forge-dialog-description'
30
+ ARIA_DESCRIPTION_ID: 'forge-dialog-description'
31
31
  };
32
32
  const classes = {
33
33
  MOVED: 'moved',
@@ -58,6 +58,8 @@ export declare class DialogCore implements IDialogCore {
58
58
  showBackdrop(): void;
59
59
  private _show;
60
60
  private _hide;
61
+ private _release;
62
+ private _tryResetFullscreenValue;
61
63
  private _applyOpen;
62
64
  private _onEscapeDismiss;
63
65
  private _onBackdropDismiss;
@@ -49,9 +49,9 @@ export class DialogCore {
49
49
  if (this._moveController) {
50
50
  this._destroyMoveController();
51
51
  }
52
- if (this._open) {
53
- this._hide();
54
- }
52
+ this._release();
53
+ this._tryResetFullscreenValue();
54
+ this._adapter.destroy();
55
55
  }
56
56
  dispatchBeforeCloseEvent() {
57
57
  const evt = new CustomEvent(DIALOG_CONSTANTS.events.BEFORE_CLOSE, {
@@ -72,10 +72,7 @@ export class DialogCore {
72
72
  this._adapter.show();
73
73
  this._adapter.addDialogFormSubmitListener(this._dialogFormSubmitListener);
74
74
  DismissibleStack.instance.add(this._adapter.hostElement);
75
- if (this._mode === 'modal') {
76
- this._adapter.addDialogCancelListener(this._escapeDismissListener);
77
- }
78
- else if (this._mode === 'inline-modal') {
75
+ if (this._mode === 'modal' || this._mode === 'inline-modal') {
79
76
  this._adapter.addDocumentListener('keydown', this._escapeDismissListener);
80
77
  }
81
78
  if (!this._persistent) {
@@ -91,21 +88,26 @@ export class DialogCore {
91
88
  this._adapter.dispatchHostEvent(new CustomEvent(DIALOG_CONSTANTS.events.OPEN, { bubbles: true, composed: true }));
92
89
  }
93
90
  async _hide() {
91
+ this._release();
92
+ await this._adapter.hide();
93
+ // Reset the fullscreen value to the original value if it was changed internally by our media query listener
94
+ this._tryResetFullscreenValue();
95
+ if (this._moveController) {
96
+ this._destroyMoveController();
97
+ }
98
+ this._adapter.dispatchHostEvent(new CustomEvent(DIALOG_CONSTANTS.events.CLOSE, { bubbles: true, composed: true }));
99
+ }
100
+ _release() {
94
101
  this._adapter.removeDialogFormSubmitListener(this._dialogFormSubmitListener);
95
- this._adapter.removeDialogCancelListener(this._escapeDismissListener);
96
102
  this._adapter.removeDocumentListener('keydown', this._escapeDismissListener);
97
103
  this._adapter.removeBackdropDismissListener(this._backdropDismissListener);
98
104
  DismissibleStack.instance.remove(this._adapter.hostElement);
99
- await this._adapter.hide();
100
- // Reset the fullscreen value to the original value if it was changed internally by our media query listener
105
+ }
106
+ _tryResetFullscreenValue() {
101
107
  if (typeof this._originalFullscreenValue === 'boolean') {
102
108
  this.fullscreen = this._originalFullscreenValue;
103
109
  }
104
110
  this._originalFullscreenValue = undefined;
105
- if (this._moveController) {
106
- this._destroyMoveController();
107
- }
108
- this._adapter.dispatchHostEvent(new CustomEvent(DIALOG_CONSTANTS.events.CLOSE, { bubbles: true, composed: true }));
109
111
  }
110
112
  async _applyOpen() {
111
113
  if (this._open) {
@@ -119,15 +121,10 @@ export class DialogCore {
119
121
  this._adapter.toggleHostAttribute(DIALOG_CONSTANTS.attributes.OPEN, this._open);
120
122
  }
121
123
  _onEscapeDismiss(evt) {
122
- if (evt.type === 'keydown') {
123
- const key = evt.key;
124
- if (key !== 'Escape' || !DismissibleStack.instance.isMostRecent(this._adapter.hostElement)) {
125
- return;
126
- }
127
- }
128
- else if (evt.type === 'cancel') {
129
- evt.preventDefault();
124
+ if (evt.key !== 'Escape' || !DismissibleStack.instance.isMostRecent(this._adapter.hostElement)) {
125
+ return;
130
126
  }
127
+ evt.preventDefault();
131
128
  if (!this._persistent) {
132
129
  this._tryClose();
133
130
  }
@@ -13,7 +13,7 @@ import { SplitViewPanelCore } from './split-view-panel-core';
13
13
  import { SplitViewPanelAdapter } from './split-view-panel-adapter';
14
14
  import { IconComponent, IconRegistry } from '../../icon';
15
15
  const template = '<template><div class=\"forge-split-view-panel\" id=\"root\" part=\"root\"><div class=\"forge-split-view-panel__handle\" id=\"handle\" part=\"handle\" role=\"separator\" aria-controls=\"content\" aria-grabbed=\"false\" tabindex=\"0\"><forge-icon class=\"forge-split-view-panel__icon\" id=\"icon\" part=\"icon\"></forge-icon><forge-state-layer target=\"handle\" id=\"state-layer\" exportparts=\"surface:state-layer\"></forge-state-layer><forge-focus-indicator inward target=\"handle\" part=\"focus-indicator\"></forge-focus-indicator></div><div class=\"forge-split-view-panel__content\" id=\"content\" part=\"content\" role=\"group\"><slot></slot></div></div></template>';
16
- const styles = '.forge-split-view-panel{display:flex;width:100%;height:100%;overflow:hidden}.forge-split-view-panel__handle{color:var(--forge-theme-text-medium,rgba(0,0,0,.6));background-color:var(--forge-theme-outline,#e0e0e0);position:relative;display:flex;flex-shrink:0;justify-content:center;align-items:center;outline:0}.forge-split-view-panel__content{flex:1;overflow:hidden}.forge-split-view-panel--closed{display:none}.forge-split-view-panel--disabled #handle{pointer-events:none}.forge-split-view-panel--disabled .forge-split-view-panel__icon{display:none}.forge-split-view-panel[orientation=horizontal]{min-width:var(--forge-split-view-handle-width,8px);width:calc(var(--forge-split-view-panel-size,unset) + var(--forge-split-view-handle-width,8px));flex-direction:row}.forge-split-view-panel[orientation=horizontal] .forge-split-view-panel__handle{width:var(--forge-split-view-handle-width,8px);cursor:var(--forge-split-view-panel-cursor)}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--closing[resizable=end]{position:absolute;top:0;left:0;animation-name:uuogxab;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes uuogxab{from{transform:none}to{transform:translateX(-100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--closing[resizable=start]{position:absolute;top:0;right:0;animation-name:uuogxb7;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes uuogxb7{from{transform:none}to{transform:translateX(100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--opening[resizable=end]{position:absolute;top:0;left:0;animation-name:uuogxby;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes uuogxby{from{transform:none}to{transform:translateX(-100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--opening[resizable=start]{position:absolute;top:0;right:0;animation-name:uuogxcb;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes uuogxcb{from{transform:none}to{transform:translateX(100%)}}.forge-split-view-panel[orientation=vertical]{min-height:var(--forge-split-view-handle-width,8px);height:calc(var(--forge-split-view-panel-size,unset) + var(--forge-split-view-handle-width,8px));flex-direction:column}.forge-split-view-panel[orientation=vertical] .forge-split-view-panel__handle{height:var(--forge-split-view-handle-width,8px);cursor:var(--forge-split-view-panel-cursor)}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--closing[resizable=end]{position:absolute;top:0;left:0;animation-name:uuogxd9;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes uuogxd9{from{transform:none}to{transform:translateY(-100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--closing[resizable=start]{position:absolute;bottom:0;left:0;animation-name:uuogxdb;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes uuogxdb{from{transform:none}to{transform:translateY(100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--opening[resizable=end]{position:absolute;top:0;left:0;animation-name:uuogxe9;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes uuogxe9{from{transform:none}to{transform:translateY(-100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--opening[resizable=start]{position:absolute;bottom:0;left:0;animation-name:uuogxf7;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes uuogxf7{from{transform:none}to{transform:translateY(100%)}}:host{z-index:var(--forge-split-view-animating-layer)!important;display:block;position:relative;height:100%;width:100%;flex:0}:host([hidden]){display:none}:host(:not([resizable=start],[resizable=end])){flex:1}:host(:not([resizable=start],[resizable=end])) .forge-split-view-panel{width:100%;height:100%;min-width:0;min-height:0}:host(:not([resizable=start],[resizable=end])) .forge-split-view-panel__handle{display:none}forge-focus-indicator{--forge-focus-indicator-active-width:2px}';
16
+ const styles = '.forge-split-view-panel{display:flex;width:100%;height:100%;overflow:hidden}.forge-split-view-panel__handle{color:var(--forge-theme-text-medium,rgba(0,0,0,.6));background-color:var(--forge-theme-outline,#e0e0e0);position:relative;display:flex;flex-shrink:0;justify-content:center;align-items:center;outline:0}.forge-split-view-panel__content{flex:1;overflow:hidden}.forge-split-view-panel--closed{display:none}.forge-split-view-panel--disabled #handle{pointer-events:none}.forge-split-view-panel--disabled .forge-split-view-panel__icon{display:none}.forge-split-view-panel[orientation=horizontal]{min-width:var(--forge-split-view-handle-width,8px);width:calc(var(--forge-split-view-panel-size,unset) + var(--forge-split-view-handle-width,8px));flex-direction:row}.forge-split-view-panel[orientation=horizontal] .forge-split-view-panel__handle{width:var(--forge-split-view-handle-width,8px);cursor:var(--forge-split-view-panel-cursor)}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--closing[resizable=end]{position:absolute;top:0;left:0;animation-name:u9e6ka3;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes u9e6ka3{from{transform:none}to{transform:translateX(-100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--closing[resizable=start]{position:absolute;top:0;right:0;animation-name:u9e6kah;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes u9e6kah{from{transform:none}to{transform:translateX(100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--opening[resizable=end]{position:absolute;top:0;left:0;animation-name:u9e6kau;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes u9e6kau{from{transform:none}to{transform:translateX(-100%)}}.forge-split-view-panel[orientation=horizontal].forge-split-view-panel--opening[resizable=start]{position:absolute;top:0;right:0;animation-name:u9e6kbu;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes u9e6kbu{from{transform:none}to{transform:translateX(100%)}}.forge-split-view-panel[orientation=vertical]{min-height:var(--forge-split-view-handle-width,8px);height:calc(var(--forge-split-view-panel-size,unset) + var(--forge-split-view-handle-width,8px));flex-direction:column}.forge-split-view-panel[orientation=vertical] .forge-split-view-panel__handle{height:var(--forge-split-view-handle-width,8px);cursor:var(--forge-split-view-panel-cursor)}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--closing[resizable=end]{position:absolute;top:0;left:0;animation-name:u9e6kcn;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes u9e6kcn{from{transform:none}to{transform:translateY(-100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--closing[resizable=start]{position:absolute;bottom:0;left:0;animation-name:u9e6kcs;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1))}@keyframes u9e6kcs{from{transform:none}to{transform:translateY(100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--opening[resizable=end]{position:absolute;top:0;left:0;animation-name:u9e6kdd;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes u9e6kdd{from{transform:none}to{transform:translateY(-100%)}}.forge-split-view-panel[orientation=vertical].forge-split-view-panel--opening[resizable=start]{position:absolute;bottom:0;left:0;animation-name:u9e6kdt;animation-duration:var(--forge-animation-duration-medium2, 300ms);animation-timing-function:var(--forge-animation-easing-standard,cubic-bezier(0.2,0,0,1));animation-direction:reverse}@keyframes u9e6kdt{from{transform:none}to{transform:translateY(100%)}}:host{z-index:var(--forge-split-view-animating-layer)!important;display:block;position:relative;height:100%;width:100%;flex:0}:host([hidden]){display:none}:host(:not([resizable=start],[resizable=end])){flex:1}:host(:not([resizable=start],[resizable=end])) .forge-split-view-panel{width:100%;height:100%;min-width:0;min-height:0}:host(:not([resizable=start],[resizable=end])) .forge-split-view-panel__handle{display:none}forge-focus-indicator{--forge-focus-indicator-active-width:2px}';
17
17
  import { StateLayerComponent } from '../../state-layer';
18
18
  import { FocusIndicatorComponent } from '../../focus-indicator';
19
19
  /**
@@ -27,7 +27,11 @@ export declare class TextFieldCore extends BaseFieldCore<ITextFieldAdapter> impl
27
27
  private _handleSlotChange;
28
28
  private _onInputAttributeChange;
29
29
  private _onClearButtonClick;
30
+ /** Responds to the `input` event from the <input> element. */
31
+ private _onInputChange;
32
+ /** Called from the `value` property setter on the <input> element. */
30
33
  private _onValueChange;
34
+ private _syncValueChange;
31
35
  private _toggleClearButtonVisibility;
32
36
  get showClear(): boolean;
33
37
  set showClear(value: boolean);
@@ -3,6 +3,7 @@
3
3
  * Copyright Tyler Technologies, Inc.
4
4
  * License: Apache-2.0
5
5
  */
6
+ import { isInstanceOf } from '../core/utils/utils';
6
7
  import { FIELD_CONSTANTS } from '../field';
7
8
  import { BaseFieldCore } from '../field/base/base-field-core';
8
9
  import { TEXT_FIELD_CONSTANTS } from './text-field-constants';
@@ -14,7 +15,7 @@ export class TextFieldCore extends BaseFieldCore {
14
15
  this._slotChangeListener = this._onSlotChange.bind(this);
15
16
  this._inputAttributeListener = this._onInputAttributeChange.bind(this);
16
17
  this._valueChangeListener = this._onValueChange.bind(this);
17
- this._inputListener = this._onValueChange.bind(this);
18
+ this._inputListener = this._onInputChange.bind(this);
18
19
  this._clearButtonClickListener = (evt) => this._onClearButtonClick(evt);
19
20
  }
20
21
  initialize() {
@@ -71,13 +72,22 @@ export class TextFieldCore extends BaseFieldCore {
71
72
  this._adapter.clearInput();
72
73
  }
73
74
  }
74
- _onValueChange(evt) {
75
- let force;
76
- // Handle the special case where a number input allows invalid characters
77
- if (evt.target?.type === 'number' && (evt.data != null || evt.target.validity.badInput)) {
78
- force = true;
75
+ /** Responds to the `input` event from the <input> element. */
76
+ _onInputChange(evt) {
77
+ let floatLabel;
78
+ // Handle the special case where a number input allows invalid characters to be entered.
79
+ // In this case, we need to force the label to float.
80
+ if (isInstanceOf(evt, InputEvent.name) && evt.target.type === 'number' && (evt.data != null || evt.target.validity.badInput)) {
81
+ floatLabel = true;
79
82
  }
80
- this._tryFloatLabel(force);
83
+ this._syncValueChange({ floatLabel });
84
+ }
85
+ /** Called from the `value` property setter on the <input> element. */
86
+ _onValueChange() {
87
+ this._syncValueChange();
88
+ }
89
+ _syncValueChange({ floatLabel = undefined } = {}) {
90
+ this._tryFloatLabel(floatLabel);
81
91
  this._toggleClearButtonVisibility();
82
92
  }
83
93
  _toggleClearButtonVisibility() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tylertech/forge",
3
3
  "description": "Tyler Forge™ Web Components library",
4
- "version": "3.6.0",
4
+ "version": "3.6.2",
5
5
  "author": "Tyler Technologies, Inc.",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {