@tylertech/forge 3.6.1 → 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.
- package/custom-elements.json +3 -3
- package/dist/lib.js +8 -8
- package/dist/lib.js.map +3 -3
- package/esm/core/utils/utils.d.ts +7 -0
- package/esm/core/utils/utils.js +9 -0
- package/esm/dialog/dialog-adapter.d.ts +3 -4
- package/esm/dialog/dialog-adapter.js +12 -14
- package/esm/dialog/dialog-core.d.ts +2 -0
- package/esm/dialog/dialog-core.js +19 -22
- package/esm/split-view/split-view-panel/split-view-panel.js +1 -1
- package/esm/text-field/text-field-core.d.ts +4 -0
- package/esm/text-field/text-field-core.js +17 -7
- package/package.json +1 -1
|
@@ -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;
|
package/esm/core/utils/utils.js
CHANGED
|
@@ -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;
|
|
@@ -66,4 +64,5 @@ export declare class DialogAdapter extends BaseAdapter<IDialogComponent> impleme
|
|
|
66
64
|
setAccessibleLabel(label: string): void;
|
|
67
65
|
setAccessibleDescription(description: string): void;
|
|
68
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
|
-
|
|
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
|
-
|
|
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
|
}
|
|
@@ -191,4 +183,10 @@ export class DialogAdapter extends BaseAdapter {
|
|
|
191
183
|
element.textContent = content;
|
|
192
184
|
return element;
|
|
193
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
|
+
}
|
|
194
192
|
}
|
|
@@ -49,9 +49,9 @@ export class DialogCore {
|
|
|
49
49
|
if (this._moveController) {
|
|
50
50
|
this._destroyMoveController();
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
100
|
-
|
|
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.
|
|
123
|
-
|
|
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:
|
|
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.
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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.
|
|
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() {
|