igniteui-webcomponents 7.3.0 → 7.3.1
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/CHANGELOG.md +41 -0
- package/README.md +30 -0
- package/components/avatar/avatar.d.ts +1 -2
- package/components/avatar/avatar.js +4 -8
- package/components/avatar/avatar.js.map +1 -1
- package/components/badge/badge.d.ts +6 -1
- package/components/badge/badge.js +8 -5
- package/components/badge/badge.js.map +1 -1
- package/components/badge/themes/badge.base.css.js +1 -1
- package/components/badge/themes/badge.base.css.js.map +1 -1
- package/components/chip/chip.d.ts +30 -14
- package/components/chip/chip.js +54 -48
- package/components/chip/chip.js.map +1 -1
- package/components/chip/themes/chip.base.css.js +1 -1
- package/components/chip/themes/chip.base.css.js.map +1 -1
- package/components/chip/themes/dark/chip.bootstrap.css.js +1 -1
- package/components/chip/themes/dark/chip.bootstrap.css.js.map +1 -1
- package/components/chip/themes/dark/chip.fluent.css.js +1 -1
- package/components/chip/themes/dark/chip.fluent.css.js.map +1 -1
- package/components/chip/themes/dark/chip.indigo.css.js +1 -1
- package/components/chip/themes/dark/chip.indigo.css.js.map +1 -1
- package/components/chip/themes/dark/chip.material.css.js +1 -1
- package/components/chip/themes/dark/chip.material.css.js.map +1 -1
- package/components/chip/themes/light/chip.bootstrap.css.js +1 -1
- package/components/chip/themes/light/chip.bootstrap.css.js.map +1 -1
- package/components/chip/themes/light/chip.fluent.css.js +1 -1
- package/components/chip/themes/light/chip.fluent.css.js.map +1 -1
- package/components/chip/themes/light/chip.indigo.css.js +1 -1
- package/components/chip/themes/light/chip.indigo.css.js.map +1 -1
- package/components/chip/themes/light/chip.material.css.js +1 -1
- package/components/chip/themes/light/chip.material.css.js.map +1 -1
- package/components/chip/themes/shared/chip.bootstrap.css.js +1 -1
- package/components/chip/themes/shared/chip.bootstrap.css.js.map +1 -1
- package/components/chip/themes/shared/chip.common.css.js +1 -1
- package/components/chip/themes/shared/chip.common.css.js.map +1 -1
- package/components/chip/themes/shared/chip.fluent.css.js +1 -1
- package/components/chip/themes/shared/chip.fluent.css.js.map +1 -1
- package/components/chip/themes/shared/chip.indigo.css.js +1 -1
- package/components/chip/themes/shared/chip.indigo.css.js.map +1 -1
- package/components/color-picker/color-picker.d.ts +2 -2
- package/components/color-picker/color-picker.js.map +1 -1
- package/components/color-picker/picker-canvas.js +2 -1
- package/components/color-picker/picker-canvas.js.map +1 -1
- package/components/textarea/textarea.d.ts +2 -15
- package/components/textarea/textarea.js +48 -93
- package/components/textarea/textarea.js.map +1 -1
- package/components/tile-manager/position.d.ts +2 -9
- package/components/tile-manager/position.js +27 -42
- package/components/tile-manager/position.js.map +1 -1
- package/components/tile-manager/resize-state.d.ts +11 -22
- package/components/tile-manager/resize-state.js +60 -119
- package/components/tile-manager/resize-state.js.map +1 -1
- package/components/tile-manager/resize-util.d.ts +3 -7
- package/components/tile-manager/resize-util.js +65 -72
- package/components/tile-manager/resize-util.js.map +1 -1
- package/components/tile-manager/serializer.d.ts +1 -1
- package/components/tile-manager/serializer.js +9 -10
- package/components/tile-manager/serializer.js.map +1 -1
- package/components/tile-manager/themes/shared/tile/tile.common.css.js +1 -1
- package/components/tile-manager/themes/shared/tile/tile.common.css.js.map +1 -1
- package/components/tile-manager/themes/tile.base.css.js +1 -1
- package/components/tile-manager/themes/tile.base.css.js.map +1 -1
- package/components/tile-manager/tile-ghost-util.js +16 -20
- package/components/tile-manager/tile-ghost-util.js.map +1 -1
- package/components/tile-manager/tile-manager.d.ts +5 -2
- package/components/tile-manager/tile-manager.js +27 -23
- package/components/tile-manager/tile-manager.js.map +1 -1
- package/components/tile-manager/tile.d.ts +32 -18
- package/components/tile-manager/tile.js +181 -161
- package/components/tile-manager/tile.js.map +1 -1
- package/components/tile-manager/types.d.ts +1 -5
- package/components/tile-manager/types.js.map +1 -1
- package/custom-elements.json +498 -853
- package/igniteui-webcomponents.css-data.json +1 -1
- package/igniteui-webcomponents.html-data.json +1 -1
- package/index.d.ts +1 -0
- package/index.js.map +1 -1
- package/internals/directives/drag.d.ts +144 -0
- package/internals/directives/drag.js +278 -0
- package/internals/directives/drag.js.map +1 -0
- package/internals/directives/resize.d.ts +109 -0
- package/internals/directives/resize.js +214 -0
- package/internals/directives/resize.js.map +1 -0
- package/internals/templates/input-shell.d.ts +12 -1
- package/internals/templates/input-shell.js +17 -10
- package/internals/templates/input-shell.js.map +1 -1
- package/internals/utils/dom.d.ts +2 -0
- package/internals/utils/dom.js +3 -0
- package/internals/utils/dom.js.map +1 -1
- package/internals/utils/events.d.ts +2 -0
- package/internals/utils/events.js +3 -0
- package/internals/utils/events.js.map +1 -1
- package/package.json +1 -1
- package/skills/README.md +1 -0
- package/web-types.json +2 -2
- package/components/resize-container/default-ghost.d.ts +0 -5
- package/components/resize-container/default-ghost.js +0 -20
- package/components/resize-container/default-ghost.js.map +0 -1
- package/components/resize-container/resize-container.d.ts +0 -60
- package/components/resize-container/resize-container.js +0 -156
- package/components/resize-container/resize-container.js.map +0 -1
- package/components/resize-container/resize-controller.d.ts +0 -46
- package/components/resize-container/resize-controller.js +0 -195
- package/components/resize-container/resize-controller.js.map +0 -1
- package/components/resize-container/themes/dark/resize-indicator.bootstrap.css.d.ts +0 -1
- package/components/resize-container/themes/dark/resize-indicator.bootstrap.css.js +0 -3
- package/components/resize-container/themes/dark/resize-indicator.bootstrap.css.js.map +0 -1
- package/components/resize-container/themes/dark/resize-indicator.fluent.css.d.ts +0 -1
- package/components/resize-container/themes/dark/resize-indicator.fluent.css.js +0 -3
- package/components/resize-container/themes/dark/resize-indicator.fluent.css.js.map +0 -1
- package/components/resize-container/themes/dark/resize-indicator.indigo.css.d.ts +0 -1
- package/components/resize-container/themes/dark/resize-indicator.indigo.css.js +0 -3
- package/components/resize-container/themes/dark/resize-indicator.indigo.css.js.map +0 -1
- package/components/resize-container/themes/dark/resize-indicator.material.css.d.ts +0 -1
- package/components/resize-container/themes/dark/resize-indicator.material.css.js +0 -3
- package/components/resize-container/themes/dark/resize-indicator.material.css.js.map +0 -1
- package/components/resize-container/themes/dark/resize-indicator.shared.css.d.ts +0 -1
- package/components/resize-container/themes/dark/resize-indicator.shared.css.js +0 -3
- package/components/resize-container/themes/dark/resize-indicator.shared.css.js.map +0 -1
- package/components/resize-container/themes/light/resize-indicator.bootstrap.css.d.ts +0 -1
- package/components/resize-container/themes/light/resize-indicator.bootstrap.css.js +0 -3
- package/components/resize-container/themes/light/resize-indicator.bootstrap.css.js.map +0 -1
- package/components/resize-container/themes/light/resize-indicator.fluent.css.d.ts +0 -1
- package/components/resize-container/themes/light/resize-indicator.fluent.css.js +0 -3
- package/components/resize-container/themes/light/resize-indicator.fluent.css.js.map +0 -1
- package/components/resize-container/themes/light/resize-indicator.indigo.css.d.ts +0 -1
- package/components/resize-container/themes/light/resize-indicator.indigo.css.js +0 -3
- package/components/resize-container/themes/light/resize-indicator.indigo.css.js.map +0 -1
- package/components/resize-container/themes/light/resize-indicator.material.css.d.ts +0 -1
- package/components/resize-container/themes/light/resize-indicator.material.css.js +0 -3
- package/components/resize-container/themes/light/resize-indicator.material.css.js.map +0 -1
- package/components/resize-container/themes/light/resize-indicator.shared.css.d.ts +0 -1
- package/components/resize-container/themes/light/resize-indicator.shared.css.js +0 -3
- package/components/resize-container/themes/light/resize-indicator.shared.css.js.map +0 -1
- package/components/resize-container/themes/resize-container.base.css.d.ts +0 -1
- package/components/resize-container/themes/resize-container.base.css.js +0 -3
- package/components/resize-container/themes/resize-container.base.css.js.map +0 -1
- package/components/resize-container/themes/shared/resize-container.common.css.d.ts +0 -1
- package/components/resize-container/themes/shared/resize-container.common.css.js +0 -3
- package/components/resize-container/themes/shared/resize-container.common.css.js.map +0 -1
- package/components/resize-container/themes/themes.d.ts +0 -2
- package/components/resize-container/themes/themes.js +0 -47
- package/components/resize-container/themes/themes.js.map +0 -1
- package/components/resize-container/types.d.ts +0 -40
- package/components/resize-container/types.js +0 -2
- package/components/resize-container/types.js.map +0 -1
- package/internals/controllers/drag.d.ts +0 -166
- package/internals/controllers/drag.js +0 -283
- package/internals/controllers/drag.js.map +0 -1
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { AsyncDirective, type DirectiveParameters, type ElementPart, type PartInfo } from 'lit/async-directive.js';
|
|
2
|
+
export type ResizeMode = 'immediate' | 'deferred';
|
|
3
|
+
export type ResizeDirection = 'horizontal' | 'vertical' | 'both';
|
|
4
|
+
export type ResizeGhostFactory = (initial: DOMRect) => HTMLElement;
|
|
5
|
+
export type ResizeCallback = (params: ResizeCallbackParams) => unknown;
|
|
6
|
+
export type ResizeCancelCallback = (state: ResizeState) => unknown;
|
|
7
|
+
export type ResizeState = {
|
|
8
|
+
/** The dimensions of the resize target at the start of the operation. */
|
|
9
|
+
initial: DOMRect;
|
|
10
|
+
/** The current dimensions of the resize target. Mutable from within the callbacks. */
|
|
11
|
+
current: DOMRect;
|
|
12
|
+
/** Difference between the current and initial width. */
|
|
13
|
+
deltaX: number;
|
|
14
|
+
/** Difference between the current and initial height. */
|
|
15
|
+
deltaY: number;
|
|
16
|
+
/** The ghost element when in deferred mode. */
|
|
17
|
+
ghost: HTMLElement | null;
|
|
18
|
+
/** The element the directive is attached to. */
|
|
19
|
+
trigger: HTMLElement | null;
|
|
20
|
+
/**
|
|
21
|
+
* When assigned from within the `end` callback, it is invoked instead of the default
|
|
22
|
+
* behavior of applying the final dimensions to the resize target.
|
|
23
|
+
*/
|
|
24
|
+
commit?: () => unknown;
|
|
25
|
+
};
|
|
26
|
+
export type ResizeCallbackParams = {
|
|
27
|
+
event: PointerEvent;
|
|
28
|
+
state: ResizeState;
|
|
29
|
+
};
|
|
30
|
+
/** Options for the resizable directive. */
|
|
31
|
+
export interface ResizableOptions {
|
|
32
|
+
/** Whether the directive will listen for and initiate resize operations. Defaults to `true`. */
|
|
33
|
+
enabled?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* The mode of the resize operation.
|
|
36
|
+
*
|
|
37
|
+
* In `immediate` mode the target element is resized in place as the pointer moves.
|
|
38
|
+
* In `deferred` mode a ghost element is created and resized instead, with the final
|
|
39
|
+
* dimensions applied to the target when the operation completes.
|
|
40
|
+
*/
|
|
41
|
+
mode?: ResizeMode;
|
|
42
|
+
/** The direction in which the element can be resized. Defaults to `both`. */
|
|
43
|
+
direction?: ResizeDirection;
|
|
44
|
+
/**
|
|
45
|
+
* The element being resized. Defaults to the element the directive is applied to.
|
|
46
|
+
*
|
|
47
|
+
* Accepts either an element or a function returning one, resolved at the start
|
|
48
|
+
* of each resize operation.
|
|
49
|
+
*/
|
|
50
|
+
target?: HTMLElement | (() => HTMLElement | null | undefined);
|
|
51
|
+
/** Factory function for the ghost element in deferred mode. */
|
|
52
|
+
ghostFactory?: ResizeGhostFactory;
|
|
53
|
+
/** The container in which the deferred ghost element is rendered. Defaults to the document body. */
|
|
54
|
+
layer?: () => HTMLElement;
|
|
55
|
+
/** The minimum width of the resizable element in pixels. */
|
|
56
|
+
minWidth?: number;
|
|
57
|
+
/** The maximum width of the resizable element in pixels. */
|
|
58
|
+
maxWidth?: number;
|
|
59
|
+
/** The minimum height of the resizable element in pixels. */
|
|
60
|
+
minHeight?: number;
|
|
61
|
+
/** The maximum height of the resizable element in pixels. */
|
|
62
|
+
maxHeight?: number;
|
|
63
|
+
/** Whether to maintain the initial aspect ratio of the resizable element. */
|
|
64
|
+
maintainAspectRatio?: boolean;
|
|
65
|
+
/** Called when a resize operation starts. Return `false` to abort the operation. */
|
|
66
|
+
start?: ResizeCallback;
|
|
67
|
+
/** Called on each pointer move during a resize operation. May mutate `state.current`. */
|
|
68
|
+
resize?: ResizeCallback;
|
|
69
|
+
/** Called when a resize operation completes. May assign `state.commit`. */
|
|
70
|
+
end?: ResizeCallback;
|
|
71
|
+
/** Called when a resize operation is cancelled with the Escape key. */
|
|
72
|
+
cancel?: ResizeCancelCallback;
|
|
73
|
+
}
|
|
74
|
+
declare class ResizableDirective extends AsyncDirective {
|
|
75
|
+
private readonly _triggerAbort;
|
|
76
|
+
private readonly _resizeAbort;
|
|
77
|
+
private _options;
|
|
78
|
+
private _host?;
|
|
79
|
+
private _operation;
|
|
80
|
+
constructor(partInfo: PartInfo);
|
|
81
|
+
private get _enabled();
|
|
82
|
+
private get _isDeferred();
|
|
83
|
+
private readonly _handlePointerDown;
|
|
84
|
+
private readonly _handlePointerMove;
|
|
85
|
+
private readonly _handlePointerEnd;
|
|
86
|
+
private readonly _handleKeydown;
|
|
87
|
+
/** Prevents native touch interactions from interfering with an enabled directive. */
|
|
88
|
+
private readonly _preventNativeBehavior;
|
|
89
|
+
private _addTriggerListeners;
|
|
90
|
+
private _resolveTarget;
|
|
91
|
+
private _createGhost;
|
|
92
|
+
private _createState;
|
|
93
|
+
private _createParams;
|
|
94
|
+
private _updateDimensions;
|
|
95
|
+
/** Applies the current dimensions of the operation as inline styles to the given element. */
|
|
96
|
+
private _applyDimensions;
|
|
97
|
+
/** Stops the current resize operation, cleaning up the ghost element and event listeners. */
|
|
98
|
+
private _dispose;
|
|
99
|
+
protected reconnected(): void;
|
|
100
|
+
protected disconnected(): void;
|
|
101
|
+
update(part: ElementPart, [options]: DirectiveParameters<this>): symbol;
|
|
102
|
+
render(_options?: ResizableOptions): symbol;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* A directive that makes an element a trigger for resizing a target element,
|
|
106
|
+
* either in place or through a deferred ghost element.
|
|
107
|
+
*/
|
|
108
|
+
export declare const resizable: (_options?: ResizableOptions | undefined) => import("lit-html/directive.js").DirectiveResult<typeof ResizableDirective>;
|
|
109
|
+
export {};
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { noChange } from 'lit';
|
|
2
|
+
import { AsyncDirective, directive, PartType, } from 'lit/async-directive.js';
|
|
3
|
+
import { createAbortHandle } from '../abort-handler.js';
|
|
4
|
+
import { escapeKey, isKey } from '../controllers/key-bindings.js';
|
|
5
|
+
import { getDefaultLayer, setStyles } from '../utils/dom.js';
|
|
6
|
+
import { preventDefault } from '../utils/events.js';
|
|
7
|
+
function createDefaultGhost({ x, y, width, height }) {
|
|
8
|
+
const element = document.createElement('div');
|
|
9
|
+
const { scrollX, scrollY } = window;
|
|
10
|
+
setStyles(element, {
|
|
11
|
+
position: 'absolute',
|
|
12
|
+
top: `${y + scrollY}px`,
|
|
13
|
+
left: `${x + scrollX}px`,
|
|
14
|
+
zIndex: '1000',
|
|
15
|
+
background: 'pink',
|
|
16
|
+
opacity: '0.85',
|
|
17
|
+
width: `${width}px`,
|
|
18
|
+
height: `${height}px`,
|
|
19
|
+
});
|
|
20
|
+
return element;
|
|
21
|
+
}
|
|
22
|
+
class ResizableDirective extends AsyncDirective {
|
|
23
|
+
constructor(partInfo) {
|
|
24
|
+
super(partInfo);
|
|
25
|
+
this._triggerAbort = createAbortHandle();
|
|
26
|
+
this._resizeAbort = createAbortHandle();
|
|
27
|
+
this._options = {};
|
|
28
|
+
this._operation = null;
|
|
29
|
+
this._handlePointerDown = (event) => {
|
|
30
|
+
if (!this._enabled || event.button !== 0 || this._operation) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const target = this._resolveTarget();
|
|
34
|
+
if (!target) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const initial = target.getBoundingClientRect();
|
|
38
|
+
this._operation = {
|
|
39
|
+
pointerId: event.pointerId,
|
|
40
|
+
target,
|
|
41
|
+
initial,
|
|
42
|
+
current: structuredClone(initial),
|
|
43
|
+
ghost: this._isDeferred ? this._createGhost(initial) : null,
|
|
44
|
+
targetStyles: { width: target.style.width, height: target.style.height },
|
|
45
|
+
};
|
|
46
|
+
if (this._options.start?.(this._createParams(event)) === false) {
|
|
47
|
+
this._dispose();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const host = this._host;
|
|
51
|
+
const { signal } = this._resizeAbort;
|
|
52
|
+
host.setPointerCapture(event.pointerId);
|
|
53
|
+
host.addEventListener('pointermove', this._handlePointerMove, { signal });
|
|
54
|
+
host.addEventListener('lostpointercapture', this._handlePointerEnd, {
|
|
55
|
+
signal,
|
|
56
|
+
});
|
|
57
|
+
host.addEventListener('contextmenu', preventDefault, { signal });
|
|
58
|
+
globalThis.addEventListener('keydown', this._handleKeydown, { signal });
|
|
59
|
+
};
|
|
60
|
+
this._handlePointerMove = (event) => {
|
|
61
|
+
if (!this._operation) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this._updateDimensions(event);
|
|
65
|
+
const params = this._createParams(event);
|
|
66
|
+
this._options.resize?.(params);
|
|
67
|
+
this._operation.current = params.state.current;
|
|
68
|
+
this._applyDimensions(this._isDeferred ? this._operation.ghost : this._operation.target);
|
|
69
|
+
};
|
|
70
|
+
this._handlePointerEnd = (event) => {
|
|
71
|
+
if (!this._operation) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const params = this._createParams(event);
|
|
75
|
+
this._options.end?.(params);
|
|
76
|
+
this._operation.current = params.state.current;
|
|
77
|
+
if (params.state.commit) {
|
|
78
|
+
params.state.commit();
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this._applyDimensions(this._operation.target);
|
|
82
|
+
}
|
|
83
|
+
this._dispose();
|
|
84
|
+
};
|
|
85
|
+
this._handleKeydown = (event) => {
|
|
86
|
+
if (!this._operation || !isKey(event, escapeKey)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
this._options.cancel?.(this._createState());
|
|
90
|
+
if (!this._isDeferred) {
|
|
91
|
+
setStyles(this._operation.target, this._operation.targetStyles);
|
|
92
|
+
}
|
|
93
|
+
this._dispose();
|
|
94
|
+
};
|
|
95
|
+
this._preventNativeBehavior = (event) => {
|
|
96
|
+
if (this._enabled) {
|
|
97
|
+
event.preventDefault();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
if (partInfo.type !== PartType.ELEMENT) {
|
|
101
|
+
throw new Error('The `resizable` directive can only be used on elements.');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
get _enabled() {
|
|
105
|
+
return this._options.enabled ?? true;
|
|
106
|
+
}
|
|
107
|
+
get _isDeferred() {
|
|
108
|
+
return this._options.mode === 'deferred';
|
|
109
|
+
}
|
|
110
|
+
_addTriggerListeners() {
|
|
111
|
+
if (!this._host) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const { signal } = this._triggerAbort;
|
|
115
|
+
this._host.addEventListener('pointerdown', this._handlePointerDown, {
|
|
116
|
+
signal,
|
|
117
|
+
});
|
|
118
|
+
this._host.addEventListener('touchstart', this._preventNativeBehavior, {
|
|
119
|
+
passive: false,
|
|
120
|
+
signal,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
_resolveTarget() {
|
|
124
|
+
const { target } = this._options;
|
|
125
|
+
return ((typeof target === 'function' ? target() : target) ?? this._host ?? null);
|
|
126
|
+
}
|
|
127
|
+
_createGhost(initial) {
|
|
128
|
+
const ghost = this._options.ghostFactory?.(initial) ?? createDefaultGhost(initial);
|
|
129
|
+
ghost.setAttribute('data-resize-ghost', '');
|
|
130
|
+
(this._options.layer?.() ?? getDefaultLayer()).append(ghost);
|
|
131
|
+
return ghost;
|
|
132
|
+
}
|
|
133
|
+
_createState() {
|
|
134
|
+
const { initial, current, ghost } = this._operation;
|
|
135
|
+
return {
|
|
136
|
+
initial,
|
|
137
|
+
current,
|
|
138
|
+
deltaX: current.width - initial.width,
|
|
139
|
+
deltaY: current.height - initial.height,
|
|
140
|
+
ghost,
|
|
141
|
+
trigger: this._host ?? null,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
_createParams(event) {
|
|
145
|
+
return { event, state: this._createState() };
|
|
146
|
+
}
|
|
147
|
+
_updateDimensions({ clientX, clientY }) {
|
|
148
|
+
const { initial, current } = this._operation;
|
|
149
|
+
const { direction = 'both', maintainAspectRatio, minWidth, maxWidth, minHeight, maxHeight, } = this._options;
|
|
150
|
+
const horizontal = direction !== 'vertical';
|
|
151
|
+
const vertical = direction !== 'horizontal';
|
|
152
|
+
let width = horizontal ? clientX - initial.x : initial.width;
|
|
153
|
+
let height = vertical ? clientY - initial.y : initial.height;
|
|
154
|
+
if (maintainAspectRatio) {
|
|
155
|
+
const ratio = initial.width / initial.height;
|
|
156
|
+
if (horizontal) {
|
|
157
|
+
height = width / ratio;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
width = height * ratio;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (minWidth != null)
|
|
164
|
+
width = Math.max(width, minWidth);
|
|
165
|
+
if (maxWidth != null)
|
|
166
|
+
width = Math.min(width, maxWidth);
|
|
167
|
+
if (minHeight != null)
|
|
168
|
+
height = Math.max(height, minHeight);
|
|
169
|
+
if (maxHeight != null)
|
|
170
|
+
height = Math.min(height, maxHeight);
|
|
171
|
+
current.width = width;
|
|
172
|
+
current.height = height;
|
|
173
|
+
}
|
|
174
|
+
_applyDimensions(element) {
|
|
175
|
+
if (element) {
|
|
176
|
+
const { current } = this._operation;
|
|
177
|
+
setStyles(element, {
|
|
178
|
+
width: `${current.width}px`,
|
|
179
|
+
height: `${current.height}px`,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
_dispose() {
|
|
184
|
+
this._resizeAbort.abort();
|
|
185
|
+
if (this._operation) {
|
|
186
|
+
const { pointerId, ghost } = this._operation;
|
|
187
|
+
if (this._host?.hasPointerCapture(pointerId)) {
|
|
188
|
+
this._host.releasePointerCapture(pointerId);
|
|
189
|
+
}
|
|
190
|
+
ghost?.remove();
|
|
191
|
+
this._operation = null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
reconnected() {
|
|
195
|
+
this._addTriggerListeners();
|
|
196
|
+
}
|
|
197
|
+
disconnected() {
|
|
198
|
+
this._dispose();
|
|
199
|
+
this._triggerAbort.abort();
|
|
200
|
+
}
|
|
201
|
+
update(part, [options]) {
|
|
202
|
+
if (this.isConnected) {
|
|
203
|
+
this._host = part.element;
|
|
204
|
+
this._options = options ?? {};
|
|
205
|
+
this._addTriggerListeners();
|
|
206
|
+
}
|
|
207
|
+
return noChange;
|
|
208
|
+
}
|
|
209
|
+
render(_options) {
|
|
210
|
+
return noChange;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
export const resizable = directive(ResizableDirective);
|
|
214
|
+
//# sourceMappingURL=resize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resize.js","sourceRoot":"","sources":["../../../src/internals/directives/resize.ts"],"names":[],"mappings":"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","sourcesContent":["import { noChange } from 'lit';\nimport {\n AsyncDirective,\n directive,\n type DirectiveParameters,\n type ElementPart,\n type PartInfo,\n PartType,\n} from 'lit/async-directive.js';\nimport { createAbortHandle } from '../abort-handler.js';\nimport { escapeKey, isKey } from '../controllers/key-bindings.js';\nimport { getDefaultLayer, setStyles } from '../utils/dom.js';\nimport { preventDefault } from '../utils/events.js';\n\nexport type ResizeMode = 'immediate' | 'deferred';\nexport type ResizeDirection = 'horizontal' | 'vertical' | 'both';\nexport type ResizeGhostFactory = (initial: DOMRect) => HTMLElement;\nexport type ResizeCallback = (params: ResizeCallbackParams) => unknown;\nexport type ResizeCancelCallback = (state: ResizeState) => unknown;\n\nexport type ResizeState = {\n /** The dimensions of the resize target at the start of the operation. */\n initial: DOMRect;\n /** The current dimensions of the resize target. Mutable from within the callbacks. */\n current: DOMRect;\n /** Difference between the current and initial width. */\n deltaX: number;\n /** Difference between the current and initial height. */\n deltaY: number;\n /** The ghost element when in deferred mode. */\n ghost: HTMLElement | null;\n /** The element the directive is attached to. */\n trigger: HTMLElement | null;\n /**\n * When assigned from within the `end` callback, it is invoked instead of the default\n * behavior of applying the final dimensions to the resize target.\n */\n commit?: () => unknown;\n};\n\nexport type ResizeCallbackParams = {\n event: PointerEvent;\n state: ResizeState;\n};\n\n/** Options for the resizable directive. */\nexport interface ResizableOptions {\n /** Whether the directive will listen for and initiate resize operations. Defaults to `true`. */\n enabled?: boolean;\n /**\n * The mode of the resize operation.\n *\n * In `immediate` mode the target element is resized in place as the pointer moves.\n * In `deferred` mode a ghost element is created and resized instead, with the final\n * dimensions applied to the target when the operation completes.\n */\n mode?: ResizeMode;\n /** The direction in which the element can be resized. Defaults to `both`. */\n direction?: ResizeDirection;\n /**\n * The element being resized. Defaults to the element the directive is applied to.\n *\n * Accepts either an element or a function returning one, resolved at the start\n * of each resize operation.\n */\n target?: HTMLElement | (() => HTMLElement | null | undefined);\n /** Factory function for the ghost element in deferred mode. */\n ghostFactory?: ResizeGhostFactory;\n /** The container in which the deferred ghost element is rendered. Defaults to the document body. */\n layer?: () => HTMLElement;\n /** The minimum width of the resizable element in pixels. */\n minWidth?: number;\n /** The maximum width of the resizable element in pixels. */\n maxWidth?: number;\n /** The minimum height of the resizable element in pixels. */\n minHeight?: number;\n /** The maximum height of the resizable element in pixels. */\n maxHeight?: number;\n /** Whether to maintain the initial aspect ratio of the resizable element. */\n maintainAspectRatio?: boolean;\n /** Called when a resize operation starts. Return `false` to abort the operation. */\n start?: ResizeCallback;\n /** Called on each pointer move during a resize operation. May mutate `state.current`. */\n resize?: ResizeCallback;\n /** Called when a resize operation completes. May assign `state.commit`. */\n end?: ResizeCallback;\n /** Called when a resize operation is cancelled with the Escape key. */\n cancel?: ResizeCancelCallback;\n}\n\ntype ResizeOperation = {\n pointerId: number;\n target: HTMLElement;\n initial: DOMRect;\n current: DOMRect;\n ghost: HTMLElement | null;\n /** Inline size styles of the target before the operation, restored on cancel. */\n targetStyles: { width: string; height: string };\n};\n\nfunction createDefaultGhost({ x, y, width, height }: DOMRect): HTMLElement {\n const element = document.createElement('div');\n const { scrollX, scrollY } = window;\n\n setStyles(element, {\n position: 'absolute',\n top: `${y + scrollY}px`,\n left: `${x + scrollX}px`,\n zIndex: '1000',\n background: 'pink',\n opacity: '0.85',\n width: `${width}px`,\n height: `${height}px`,\n });\n\n return element;\n}\n\nclass ResizableDirective extends AsyncDirective {\n private readonly _triggerAbort = createAbortHandle();\n private readonly _resizeAbort = createAbortHandle();\n\n private _options: ResizableOptions = {};\n private _host?: HTMLElement;\n private _operation: ResizeOperation | null = null;\n\n constructor(partInfo: PartInfo) {\n super(partInfo);\n\n if (partInfo.type !== PartType.ELEMENT) {\n throw new Error(\n 'The `resizable` directive can only be used on elements.'\n );\n }\n }\n\n private get _enabled(): boolean {\n return this._options.enabled ?? true;\n }\n\n private get _isDeferred(): boolean {\n return this._options.mode === 'deferred';\n }\n\n // #region Event handlers\n\n private readonly _handlePointerDown = (event: PointerEvent): void => {\n if (!this._enabled || event.button !== 0 || this._operation) {\n return;\n }\n\n const target = this._resolveTarget();\n if (!target) {\n return;\n }\n\n const initial = target.getBoundingClientRect();\n\n this._operation = {\n pointerId: event.pointerId,\n target,\n initial,\n current: structuredClone(initial),\n ghost: this._isDeferred ? this._createGhost(initial) : null,\n targetStyles: { width: target.style.width, height: target.style.height },\n };\n\n if (this._options.start?.(this._createParams(event)) === false) {\n this._dispose();\n return;\n }\n\n const host = this._host!;\n const { signal } = this._resizeAbort;\n\n host.setPointerCapture(event.pointerId);\n host.addEventListener('pointermove', this._handlePointerMove, { signal });\n host.addEventListener('lostpointercapture', this._handlePointerEnd, {\n signal,\n });\n host.addEventListener('contextmenu', preventDefault, { signal });\n globalThis.addEventListener('keydown', this._handleKeydown, { signal });\n };\n\n private readonly _handlePointerMove = (event: PointerEvent): void => {\n if (!this._operation) {\n return;\n }\n\n this._updateDimensions(event);\n\n const params = this._createParams(event);\n this._options.resize?.(params);\n this._operation.current = params.state.current;\n\n this._applyDimensions(\n this._isDeferred ? this._operation.ghost : this._operation.target\n );\n };\n\n private readonly _handlePointerEnd = (event: PointerEvent): void => {\n if (!this._operation) {\n return;\n }\n\n const params = this._createParams(event);\n this._options.end?.(params);\n this._operation.current = params.state.current;\n\n if (params.state.commit) {\n params.state.commit();\n } else {\n this._applyDimensions(this._operation.target);\n }\n\n this._dispose();\n };\n\n private readonly _handleKeydown = (event: KeyboardEvent): void => {\n if (!this._operation || !isKey(event, escapeKey)) {\n return;\n }\n\n this._options.cancel?.(this._createState());\n\n if (!this._isDeferred) {\n setStyles(this._operation.target, this._operation.targetStyles);\n }\n\n this._dispose();\n };\n\n // #endregion\n\n // #region Internal API\n\n /** Prevents native touch interactions from interfering with an enabled directive. */\n private readonly _preventNativeBehavior = (event: Event): void => {\n if (this._enabled) {\n event.preventDefault();\n }\n };\n\n private _addTriggerListeners(): void {\n if (!this._host) {\n return;\n }\n\n const { signal } = this._triggerAbort;\n\n this._host.addEventListener('pointerdown', this._handlePointerDown, {\n signal,\n });\n this._host.addEventListener('touchstart', this._preventNativeBehavior, {\n passive: false,\n signal,\n });\n }\n\n private _resolveTarget(): HTMLElement | null {\n const { target } = this._options;\n return (\n (typeof target === 'function' ? target() : target) ?? this._host ?? null\n );\n }\n\n private _createGhost(initial: DOMRect): HTMLElement {\n const ghost =\n this._options.ghostFactory?.(initial) ?? createDefaultGhost(initial);\n\n ghost.setAttribute('data-resize-ghost', '');\n (this._options.layer?.() ?? getDefaultLayer()).append(ghost);\n return ghost;\n }\n\n private _createState(): ResizeState {\n const { initial, current, ghost } = this._operation!;\n\n return {\n initial,\n current,\n deltaX: current.width - initial.width,\n deltaY: current.height - initial.height,\n ghost,\n trigger: this._host ?? null,\n };\n }\n\n private _createParams(event: PointerEvent): ResizeCallbackParams {\n return { event, state: this._createState() };\n }\n\n private _updateDimensions({ clientX, clientY }: PointerEvent): void {\n const { initial, current } = this._operation!;\n const {\n direction = 'both',\n maintainAspectRatio,\n minWidth,\n maxWidth,\n minHeight,\n maxHeight,\n } = this._options;\n\n const horizontal = direction !== 'vertical';\n const vertical = direction !== 'horizontal';\n\n let width = horizontal ? clientX - initial.x : initial.width;\n let height = vertical ? clientY - initial.y : initial.height;\n\n if (maintainAspectRatio) {\n const ratio = initial.width / initial.height;\n\n if (horizontal) {\n height = width / ratio;\n } else {\n width = height * ratio;\n }\n }\n\n if (minWidth != null) width = Math.max(width, minWidth);\n if (maxWidth != null) width = Math.min(width, maxWidth);\n if (minHeight != null) height = Math.max(height, minHeight);\n if (maxHeight != null) height = Math.min(height, maxHeight);\n\n current.width = width;\n current.height = height;\n }\n\n /** Applies the current dimensions of the operation as inline styles to the given element. */\n private _applyDimensions(element: HTMLElement | null): void {\n if (element) {\n const { current } = this._operation!;\n setStyles(element, {\n width: `${current.width}px`,\n height: `${current.height}px`,\n });\n }\n }\n\n /** Stops the current resize operation, cleaning up the ghost element and event listeners. */\n private _dispose(): void {\n this._resizeAbort.abort();\n\n if (this._operation) {\n const { pointerId, ghost } = this._operation;\n\n if (this._host?.hasPointerCapture(pointerId)) {\n this._host.releasePointerCapture(pointerId);\n }\n\n ghost?.remove();\n this._operation = null;\n }\n }\n\n // #endregion\n\n protected override reconnected(): void {\n this._addTriggerListeners();\n }\n\n protected override disconnected(): void {\n this._dispose();\n this._triggerAbort.abort();\n }\n\n public override update(\n part: ElementPart,\n [options]: DirectiveParameters<this>\n ) {\n if (this.isConnected) {\n this._host = part.element as HTMLElement;\n this._options = options ?? {};\n this._addTriggerListeners();\n }\n return noChange;\n }\n\n public render(_options?: ResizableOptions) {\n return noChange;\n }\n}\n\n/**\n * A directive that makes an element a trigger for resizing a target element,\n * either in place or through a deferred ghost element.\n */\nexport const resizable = directive(ResizableDirective);\n"]}
|
|
@@ -22,10 +22,21 @@ export interface InputShellOptions {
|
|
|
22
22
|
renderInput: () => TemplateResult;
|
|
23
23
|
/** Optional renderer for components that need extra parts inside the container (e.g. file-input). */
|
|
24
24
|
renderFileParts?: () => TemplateResult | typeof nothing;
|
|
25
|
+
/**
|
|
26
|
+
* Container part names contributed only by the material notch layout
|
|
27
|
+
* (e.g. the `placeholder` part of `igc-textarea`).
|
|
28
|
+
*/
|
|
29
|
+
materialParts?: Record<string, boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Whether the prefix/suffix wrappers are hidden while their slot has no
|
|
32
|
+
* visible assigned elements, driven by the `prefixed` and `suffixed` entries
|
|
33
|
+
* of `containerParts`. Off by default, so the wrappers always render.
|
|
34
|
+
*/
|
|
35
|
+
hideEmptyAffixes?: boolean;
|
|
25
36
|
}
|
|
26
37
|
/**
|
|
27
38
|
* Renders the shared input chrome (label, prefix, suffix, validator container)
|
|
28
39
|
* around a leaf-provided input template, switching layouts between the
|
|
29
40
|
* material notch and the standard flow.
|
|
30
41
|
*/
|
|
31
|
-
export declare function renderInputShell(host: IgcFormControl, { containerParts, renderFileParts, renderInput, theme, label, labelId, }: InputShellOptions): TemplateResult;
|
|
42
|
+
export declare function renderInputShell(host: IgcFormControl, { containerParts, materialParts, hideEmptyAffixes, renderFileParts, renderInput, theme, label, labelId, }: InputShellOptions): TemplateResult;
|
|
@@ -20,24 +20,31 @@ function renderLabel(forId, label) {
|
|
|
20
20
|
? html `<label part="label" for=${forId}>${label}</label>`
|
|
21
21
|
: nothing;
|
|
22
22
|
}
|
|
23
|
-
function
|
|
24
|
-
return html `<div part
|
|
23
|
+
function renderAffix(name, hidden) {
|
|
24
|
+
return html `<div part=${name} ?hidden=${hidden}>
|
|
25
|
+
<slot name=${name}></slot>
|
|
26
|
+
</div>`;
|
|
25
27
|
}
|
|
26
|
-
function
|
|
27
|
-
return html `<div part="suffix"><slot name="suffix"></slot></div>`;
|
|
28
|
-
}
|
|
29
|
-
export function renderInputShell(host, { containerParts, renderFileParts, renderInput, theme, label, labelId, }) {
|
|
28
|
+
export function renderInputShell(host, { containerParts, materialParts, hideEmptyAffixes = false, renderFileParts, renderInput, theme, label, labelId, }) {
|
|
30
29
|
const validator = IgcValidationContainerComponent.create(host);
|
|
31
30
|
const input = renderInput.call(host);
|
|
32
31
|
const fileParts = renderFileParts?.call(host) ?? nothing;
|
|
32
|
+
const prefix = renderAffix('prefix', hideEmptyAffixes && !containerParts.prefixed);
|
|
33
|
+
const suffix = renderAffix('suffix', hideEmptyAffixes && !containerParts.suffixed);
|
|
33
34
|
if (theme === 'material') {
|
|
34
35
|
return html `
|
|
35
|
-
<div
|
|
36
|
-
|
|
36
|
+
<div
|
|
37
|
+
part=${partMap({
|
|
38
|
+
...containerParts,
|
|
39
|
+
...materialParts,
|
|
40
|
+
labelled: !!label,
|
|
41
|
+
})}
|
|
42
|
+
>
|
|
43
|
+
<div part="start">${prefix}</div>
|
|
37
44
|
${input}${fileParts}
|
|
38
45
|
<div part="notch">${renderLabel(labelId, label)}</div>
|
|
39
46
|
<div part="filler"></div>
|
|
40
|
-
<div part="end">${
|
|
47
|
+
<div part="end">${suffix}</div>
|
|
41
48
|
</div>
|
|
42
49
|
${validator}
|
|
43
50
|
`;
|
|
@@ -45,7 +52,7 @@ export function renderInputShell(host, { containerParts, renderFileParts, render
|
|
|
45
52
|
return html `
|
|
46
53
|
${renderLabel(labelId, label)}
|
|
47
54
|
<div part=${partMap(containerParts)}>
|
|
48
|
-
${
|
|
55
|
+
${prefix}${fileParts}${input}${suffix}
|
|
49
56
|
</div>
|
|
50
57
|
${validator}
|
|
51
58
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-shell.js","sourceRoot":"","sources":["../../../src/internals/templates/input-shell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAuB,MAAM,KAAK,CAAC;AACzD,OAAO,+BAA+B,MAAM,+DAA+D,CAAC;AAG5G,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,CAAC,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAOtD,MAAM,UAAU,qBAAqB,CACnC,KAAuE,EACvE,IAAY,EACZ,MAAe;IAEf,OAAO;QACL,CAAC,IAAI,CAAC,EAAE,IAAI;QACZ,QAAQ,EAAE,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE;YAC5C,QAAQ,EAAE,+BAA+B;SAC1C,CAAC;QACF,QAAQ,EAAE,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE;YAC5C,QAAQ,EAAE,+BAA+B;SAC1C,CAAC;QACF,MAAM;KACP,CAAC;AACJ,CAAC;
|
|
1
|
+
{"version":3,"file":"input-shell.js","sourceRoot":"","sources":["../../../src/internals/templates/input-shell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAuB,MAAM,KAAK,CAAC;AACzD,OAAO,+BAA+B,MAAM,+DAA+D,CAAC;AAG5G,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,CAAC,MAAM,WAAW,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAOtD,MAAM,UAAU,qBAAqB,CACnC,KAAuE,EACvE,IAAY,EACZ,MAAe;IAEf,OAAO;QACL,CAAC,IAAI,CAAC,EAAE,IAAI;QACZ,QAAQ,EAAE,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE;YAC5C,QAAQ,EAAE,+BAA+B;SAC1C,CAAC;QACF,QAAQ,EAAE,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE;YAC5C,QAAQ,EAAE,+BAA+B;SAC1C,CAAC;QACF,MAAM;KACP,CAAC;AACJ,CAAC;AA4BD,SAAS,WAAW,CAAC,KAAa,EAAE,KAAa;IAC/C,OAAO,KAAK;QACV,CAAC,CAAC,IAAI,CAAA,2BAA2B,KAAK,IAAI,KAAK,UAAU;QACzD,CAAC,CAAC,OAAO,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,IAAyB,EAAE,MAAe;IAC7D,OAAO,IAAI,CAAA,aAAa,IAAI,YAAY,MAAM;iBAC/B,IAAI;SACZ,CAAC;AACV,CAAC;AAOD,MAAM,UAAU,gBAAgB,CAC9B,IAAoB,EACpB,EACE,cAAc,EACd,aAAa,EACb,gBAAgB,GAAG,KAAK,EACxB,eAAe,EACf,WAAW,EACX,KAAK,EACL,KAAK,EACL,OAAO,GACW;IAEpB,MAAM,SAAS,GAAG,+BAA+B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC;IACzD,MAAM,MAAM,GAAG,WAAW,CACxB,QAAQ,EACR,gBAAgB,IAAI,CAAC,cAAc,CAAC,QAAQ,CAC7C,CAAC;IACF,MAAM,MAAM,GAAG,WAAW,CACxB,QAAQ,EACR,gBAAgB,IAAI,CAAC,cAAc,CAAC,QAAQ,CAC7C,CAAC;IAEF,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,OAAO,IAAI,CAAA;;eAEA,OAAO,CAAC;YACb,GAAG,cAAc;YACjB,GAAG,aAAa;YAChB,QAAQ,EAAE,CAAC,CAAC,KAAK;SAClB,CAAC;;4BAEkB,MAAM;UACxB,KAAK,GAAG,SAAS;4BACC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC;;0BAE7B,MAAM;;QAExB,SAAS;KACZ,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAA;MACP,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC;gBACjB,OAAO,CAAC,cAAc,CAAC;QAC/B,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM;;MAErC,SAAS;GACZ,CAAC;AACJ,CAAC","sourcesContent":["import { html, nothing, type TemplateResult } from 'lit';\nimport IgcValidationContainerComponent from '../../components/validation-container/validation-container.js';\nimport type { SlotController } from '../controllers/slot.js';\nimport type { IgcFormControl } from '../mixins/forms/types.js';\nimport { partMap } from '../part-map.js';\nimport { createIdGenerator } from '../utils/strings.js';\n\n/** Returns a unique id for native input elements rendered by input components. */\nexport const nextInputId = createIdGenerator('input');\n\n/**\n * Resolves the shared container part names of an input-like component based\n * on its current slotted and filled state.\n * Used to apply conditional styling via CSS parts.\n */\nexport function resolveInputPartNames(\n slots: Pick<SlotController<'prefix' | 'suffix'>, 'hasAssignedElements'>,\n base: string,\n filled: boolean\n): Record<string, boolean> {\n return {\n [base]: true,\n prefixed: slots.hasAssignedElements('prefix', {\n selector: '[slot=\"prefix\"]:not([hidden])',\n }),\n suffixed: slots.hasAssignedElements('suffix', {\n selector: '[slot=\"suffix\"]:not([hidden])',\n }),\n filled,\n };\n}\n\nexport interface InputShellOptions {\n /** Active theme name. The `material` theme uses the notch layout. */\n theme: string;\n /** The label text. Empty string skips label rendering. */\n label: string;\n /** The id of the input element used by the label `for` attribute. */\n labelId: string;\n /** Resolved part-name map for the container element. */\n containerParts: Record<string, boolean>;\n /** Renders the native `<input>` element. */\n renderInput: () => TemplateResult;\n /** Optional renderer for components that need extra parts inside the container (e.g. file-input). */\n renderFileParts?: () => TemplateResult | typeof nothing;\n /**\n * Container part names contributed only by the material notch layout\n * (e.g. the `placeholder` part of `igc-textarea`).\n */\n materialParts?: Record<string, boolean>;\n /**\n * Whether the prefix/suffix wrappers are hidden while their slot has no\n * visible assigned elements, driven by the `prefixed` and `suffixed` entries\n * of `containerParts`. Off by default, so the wrappers always render.\n */\n hideEmptyAffixes?: boolean;\n}\n\nfunction renderLabel(forId: string, label: string) {\n return label\n ? html`<label part=\"label\" for=${forId}>${label}</label>`\n : nothing;\n}\n\nfunction renderAffix(name: 'prefix' | 'suffix', hidden: boolean) {\n return html`<div part=${name} ?hidden=${hidden}>\n <slot name=${name}></slot>\n </div>`;\n}\n\n/**\n * Renders the shared input chrome (label, prefix, suffix, validator container)\n * around a leaf-provided input template, switching layouts between the\n * material notch and the standard flow.\n */\nexport function renderInputShell(\n host: IgcFormControl,\n {\n containerParts,\n materialParts,\n hideEmptyAffixes = false,\n renderFileParts,\n renderInput,\n theme,\n label,\n labelId,\n }: InputShellOptions\n): TemplateResult {\n const validator = IgcValidationContainerComponent.create(host);\n const input = renderInput.call(host);\n const fileParts = renderFileParts?.call(host) ?? nothing;\n const prefix = renderAffix(\n 'prefix',\n hideEmptyAffixes && !containerParts.prefixed\n );\n const suffix = renderAffix(\n 'suffix',\n hideEmptyAffixes && !containerParts.suffixed\n );\n\n if (theme === 'material') {\n return html`\n <div\n part=${partMap({\n ...containerParts,\n ...materialParts,\n labelled: !!label,\n })}\n >\n <div part=\"start\">${prefix}</div>\n ${input}${fileParts}\n <div part=\"notch\">${renderLabel(labelId, label)}</div>\n <div part=\"filler\"></div>\n <div part=\"end\">${suffix}</div>\n </div>\n ${validator}\n `;\n }\n\n return html`\n ${renderLabel(labelId, label)}\n <div part=${partMap(containerParts)}>\n ${prefix}${fileParts}${input}${suffix}\n </div>\n ${validator}\n `;\n}\n"]}
|
package/internals/utils/dom.d.ts
CHANGED
|
@@ -91,6 +91,8 @@ export declare function getScaleFactor(element: HTMLElement): {
|
|
|
91
91
|
export declare function roundByDPR(value: number): number;
|
|
92
92
|
/** Null-safe `Element.scrollIntoView` defaulting to the nearest block/inline position. */
|
|
93
93
|
export declare function scrollIntoView(element?: HTMLElement | null, config?: ScrollIntoViewOptions): void;
|
|
94
|
+
/** Returns the default containing layer for floating elements such as drag and resize ghosts. */
|
|
95
|
+
export declare function getDefaultLayer(): HTMLElement;
|
|
94
96
|
/** Applies the given CSS declarations to the inline style of the element. */
|
|
95
97
|
export declare function setStyles(element: HTMLElement, styles: Partial<CSSStyleDeclaration>): void;
|
|
96
98
|
/** Returns whether the given input has at least one selected file. */
|
package/internals/utils/dom.js
CHANGED
|
@@ -129,6 +129,9 @@ export function scrollIntoView(element, config) {
|
|
|
129
129
|
inline: 'nearest',
|
|
130
130
|
}, config));
|
|
131
131
|
}
|
|
132
|
+
export function getDefaultLayer() {
|
|
133
|
+
return document.body;
|
|
134
|
+
}
|
|
132
135
|
export function setStyles(element, styles) {
|
|
133
136
|
merge(element.style, styles);
|
|
134
137
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../../../src/internals/utils/dom.ts"],"names":[],"mappings":"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","sourcesContent":["import { isServer } from 'lit';\nimport { asNumber, clamp, numberInRangeInclusive } from './math.js';\nimport { merge } from './objects.js';\nimport { isDefined } from './types.js';\n\n/**\n * Returns whether an element has a Left-to-Right directionality.\n */\nexport function isLTR(element: HTMLElement) {\n return element.matches(':dir(ltr)');\n}\n\nconst LENGTH_PROPERTY = '--igc-resolved-length';\n\nconst SUPPORTS_REGISTERED_PROPERTIES =\n !isServer && typeof CSS !== 'undefined' && 'registerProperty' in CSS;\n\nlet lengthPropertyUsable: boolean | undefined;\n\nfunction canResolveLengths(): boolean {\n if (lengthPropertyUsable === undefined) {\n lengthPropertyUsable = SUPPORTS_REGISTERED_PROPERTIES;\n\n if (lengthPropertyUsable) {\n try {\n CSS.registerProperty({\n name: LENGTH_PROPERTY,\n syntax: '<length>',\n inherits: false,\n initialValue: '0px',\n });\n } catch {\n // The descriptor is a constant, so the only realistic rejection is a\n // duplicate registration from another bundle instance - which leaves\n // the property just as usable.\n }\n }\n }\n\n return lengthPropertyUsable;\n}\n\n/**\n * Resolves a CSS length to pixels in the context of `element`.\n *\n * A registered custom property computes to an absolute length, which lets the\n * browser do the conversion for font, viewport and container relative units\n * instead of them being read as raw numbers. Percentages are not lengths -\n * resolve those against whatever basis applies to the property at hand.\n *\n * Returns 0 for percentages, for values that are not valid lengths, and where\n * the resolution is unavailable - during server-side rendering, or without\n * support for registered custom properties. Guessing from the raw token would\n * read `5rem` as 5 pixels, so callers get an obvious zero instead.\n *\n * @example\n * ```typescript\n * resolveCssLength(element, '5rem'); // 80\n * resolveCssLength(element, '2em'); // 2 x the element font size\n * ```\n */\nexport function resolveCssLength(element: HTMLElement, value: string): number {\n if (!canResolveLengths()) {\n return 0;\n }\n\n const { style } = element;\n const previous = style.getPropertyValue(LENGTH_PROPERTY);\n const priority = style.getPropertyPriority(LENGTH_PROPERTY);\n\n style.setProperty(LENGTH_PROPERTY, value);\n const resolved = getComputedStyle(element).getPropertyValue(LENGTH_PROPERTY);\n\n // Restore rather than remove - the caller may be using the property itself.\n if (previous) {\n style.setProperty(LENGTH_PROPERTY, previous, priority);\n } else {\n style.removeProperty(LENGTH_PROPERTY);\n }\n\n return asNumber(resolved);\n}\n\nexport type IterNodesOptions<T = Node> = {\n show?: keyof typeof NodeFilter;\n filter?: (node: T) => boolean;\n};\n\nfunction createNodeFilter<T extends Node>(predicate: (node: T) => boolean) {\n return {\n acceptNode: (node: T): number =>\n predicate(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP,\n };\n}\n\n/**\n * Iterates over the DOM subtree of `root` in document order, yielding the nodes\n * matching the passed {@link IterNodesOptions | options}.\n *\n * @example\n * ```typescript\n * for (const button of iterNodes<HTMLButtonElement>(root, { show: 'SHOW_ELEMENT', filter: isButton })) { ... }\n * ```\n */\nexport function* iterNodes<T extends Node>(\n root: Node,\n options?: IterNodesOptions<T>\n): Generator<T> {\n if (!isDefined(globalThis.document)) {\n return;\n }\n\n const whatToShow = options?.show\n ? NodeFilter[options.show]\n : NodeFilter.SHOW_ALL;\n\n const nodeFilter = options?.filter\n ? createNodeFilter(options.filter)\n : undefined;\n\n const treeWalker = document.createTreeWalker(root, whatToShow, nodeFilter);\n\n while (treeWalker.nextNode()) {\n yield treeWalker.currentNode as T;\n }\n}\n\n/**\n * Iterates over `node` and its ancestors, crossing shadow DOM boundaries.\n *\n * Shadow roots are traversed through their host, so only elements are yielded.\n *\n * @example\n * ```typescript\n * for (const ancestor of iterAncestors(element)) { ... }\n * ```\n */\nexport function* iterAncestors(node?: Node | null): Generator<Element> {\n let current: Node | null | undefined = node;\n\n while (current) {\n if (isElement(current)) {\n yield current;\n }\n\n current = current instanceof ShadowRoot ? current.host : current.parentNode;\n }\n}\n\n/** Returns the root node (document or shadow root) of the given element. */\nexport function getRoot(\n element: Element,\n options?: GetRootNodeOptions\n): Document | ShadowRoot {\n return element.getRootNode(options) as Document | ShadowRoot;\n}\n\n/** Returns the element with the given id in the root node of `root`, if any. */\nexport function getElementByIdFromRoot(root: HTMLElement, id: string) {\n return getRoot(root).getElementById(id);\n}\n\nexport function isElement(node: unknown): node is Element {\n return node instanceof Node && node.nodeType === Node.ELEMENT_NODE;\n}\n\nexport function isDocument(node: unknown): node is Document {\n return node instanceof Node && node.nodeType === Node.DOCUMENT_NODE;\n}\n\n/** Returns the center x/y coordinate of a given element. */\nexport function getCenterPoint(element: Element): { x: number; y: number } {\n const { left, top, width, height } = element.getBoundingClientRect();\n\n return {\n x: left + width * 0.5,\n y: top + height * 0.5,\n };\n}\n\n/**\n * Maps a pointer's `clientX` coordinate to a fraction in the [0, 1] range of the\n * element's bounding box width, measured from the element's logical start edge -\n * the left edge when `ltr` is true, the right one otherwise.\n *\n * Returns 0 for an element without layout.\n *\n * @example\n * ```typescript\n * // Pointer 30px into a 120px wide element\n * pointToFraction(element, event.clientX); // 0.25\n * pointToFraction(element, event.clientX, false); // 0.75\n * ```\n */\nexport function pointToFraction(\n element: Element,\n clientX: number,\n ltr = true\n): number {\n const { left, right, width } = element.getBoundingClientRect();\n\n if (width === 0) {\n return 0;\n }\n\n return clamp((ltr ? clientX - left : right - clientX) / width, 0, 1);\n}\n\n/**\n * Concatenates the text content of the given nodes into a single string,\n * trimmed and with consecutive whitespace collapsed.\n *\n * Useful for deriving an accessible label from projected content.\n */\nexport function normalizedTextContent(nodes: Iterable<Node>): string {\n let text = '';\n\n for (const node of nodes) {\n text += node.textContent ?? '';\n }\n\n return text.trim().replace(/\\s+/gu, ' ');\n}\n\n/** Returns whether the given client coordinates lie within the bounding box of the element. */\nexport function isPointInsideElement(\n element: Element,\n x: number,\n y: number\n): boolean {\n const { left, right, top, bottom } = element.getBoundingClientRect();\n return (\n numberInRangeInclusive(x, left, right) &&\n numberInRangeInclusive(y, top, bottom)\n );\n}\n\n/** Returns the scale factor of a given element based on its bounding client rect and offset dimensions. */\nexport function getScaleFactor(element: HTMLElement): { x: number; y: number } {\n const { offsetWidth, offsetHeight } = element;\n const { width, height } = element.getBoundingClientRect();\n return { x: offsetWidth / width || 1, y: offsetHeight / height || 1 };\n}\n\n/** Rounds a CSS pixel value to the closest device-pixel boundary to avoid blurry rendering. */\nexport function roundByDPR(value: number): number {\n const dpr = globalThis.devicePixelRatio || 1;\n return Math.round(value * dpr) / dpr;\n}\n\n/** Null-safe `Element.scrollIntoView` defaulting to the nearest block/inline position. */\nexport function scrollIntoView(\n element?: HTMLElement | null,\n config?: ScrollIntoViewOptions\n): void {\n if (!element) {\n return;\n }\n\n element.scrollIntoView(\n Object.assign(\n {\n behavior: 'auto',\n block: 'nearest',\n inline: 'nearest',\n },\n config\n )\n );\n}\n\n/** Applies the given CSS declarations to the inline style of the element. */\nexport function setStyles(\n element: HTMLElement,\n styles: Partial<CSSStyleDeclaration>\n): void {\n merge(element.style, styles);\n}\n\n/** Returns whether the given input has at least one selected file. */\nexport function hasFiles(input: { files: FileList | null }): boolean {\n return input.files != null && input.files.length > 0;\n}\n\n/**\n * Returns whether the given element is currently an open popover or not.\n * This is useful to determine if the popover is open without relying on the `open` property, which may not be in sync with the actual popover state if the opening/closing animations are still running.\n * Note: This function only works for elements that use the `:popover-open` pseudo-class to indicate\n */\nexport function isPopoverOpen(element?: Element): boolean {\n return element?.matches(':popover-open') ?? false;\n}\n\n/**\n * Returns whether the given element, or any of its ancestors across shadow DOM\n * boundaries, is positioned as `sticky`.\n */\nexport function hasStickyAncestor(element: Element): boolean {\n for (const ancestor of iterAncestors(element)) {\n if (getComputedStyle(ancestor).position === 'sticky') {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Returns the nearest visible ancestor of a given node, traversing through shadow DOM boundaries if necessary. If no visible ancestor is found, returns null.\n */\nexport function getVisibleAncestor(startNode: Node): HTMLElement | null {\n for (const ancestor of iterAncestors(startNode.parentNode)) {\n if (ancestor instanceof HTMLElement && ancestor.checkVisibility()) {\n return ancestor;\n }\n }\n\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../../../src/internals/utils/dom.ts"],"names":[],"mappings":"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","sourcesContent":["import { isServer } from 'lit';\nimport { asNumber, clamp, numberInRangeInclusive } from './math.js';\nimport { merge } from './objects.js';\nimport { isDefined } from './types.js';\n\n/**\n * Returns whether an element has a Left-to-Right directionality.\n */\nexport function isLTR(element: HTMLElement) {\n return element.matches(':dir(ltr)');\n}\n\nconst LENGTH_PROPERTY = '--igc-resolved-length';\n\nconst SUPPORTS_REGISTERED_PROPERTIES =\n !isServer && typeof CSS !== 'undefined' && 'registerProperty' in CSS;\n\nlet lengthPropertyUsable: boolean | undefined;\n\nfunction canResolveLengths(): boolean {\n if (lengthPropertyUsable === undefined) {\n lengthPropertyUsable = SUPPORTS_REGISTERED_PROPERTIES;\n\n if (lengthPropertyUsable) {\n try {\n CSS.registerProperty({\n name: LENGTH_PROPERTY,\n syntax: '<length>',\n inherits: false,\n initialValue: '0px',\n });\n } catch {\n // The descriptor is a constant, so the only realistic rejection is a\n // duplicate registration from another bundle instance - which leaves\n // the property just as usable.\n }\n }\n }\n\n return lengthPropertyUsable;\n}\n\n/**\n * Resolves a CSS length to pixels in the context of `element`.\n *\n * A registered custom property computes to an absolute length, which lets the\n * browser do the conversion for font, viewport and container relative units\n * instead of them being read as raw numbers. Percentages are not lengths -\n * resolve those against whatever basis applies to the property at hand.\n *\n * Returns 0 for percentages, for values that are not valid lengths, and where\n * the resolution is unavailable - during server-side rendering, or without\n * support for registered custom properties. Guessing from the raw token would\n * read `5rem` as 5 pixels, so callers get an obvious zero instead.\n *\n * @example\n * ```typescript\n * resolveCssLength(element, '5rem'); // 80\n * resolveCssLength(element, '2em'); // 2 x the element font size\n * ```\n */\nexport function resolveCssLength(element: HTMLElement, value: string): number {\n if (!canResolveLengths()) {\n return 0;\n }\n\n const { style } = element;\n const previous = style.getPropertyValue(LENGTH_PROPERTY);\n const priority = style.getPropertyPriority(LENGTH_PROPERTY);\n\n style.setProperty(LENGTH_PROPERTY, value);\n const resolved = getComputedStyle(element).getPropertyValue(LENGTH_PROPERTY);\n\n // Restore rather than remove - the caller may be using the property itself.\n if (previous) {\n style.setProperty(LENGTH_PROPERTY, previous, priority);\n } else {\n style.removeProperty(LENGTH_PROPERTY);\n }\n\n return asNumber(resolved);\n}\n\nexport type IterNodesOptions<T = Node> = {\n show?: keyof typeof NodeFilter;\n filter?: (node: T) => boolean;\n};\n\nfunction createNodeFilter<T extends Node>(predicate: (node: T) => boolean) {\n return {\n acceptNode: (node: T): number =>\n predicate(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP,\n };\n}\n\n/**\n * Iterates over the DOM subtree of `root` in document order, yielding the nodes\n * matching the passed {@link IterNodesOptions | options}.\n *\n * @example\n * ```typescript\n * for (const button of iterNodes<HTMLButtonElement>(root, { show: 'SHOW_ELEMENT', filter: isButton })) { ... }\n * ```\n */\nexport function* iterNodes<T extends Node>(\n root: Node,\n options?: IterNodesOptions<T>\n): Generator<T> {\n if (!isDefined(globalThis.document)) {\n return;\n }\n\n const whatToShow = options?.show\n ? NodeFilter[options.show]\n : NodeFilter.SHOW_ALL;\n\n const nodeFilter = options?.filter\n ? createNodeFilter(options.filter)\n : undefined;\n\n const treeWalker = document.createTreeWalker(root, whatToShow, nodeFilter);\n\n while (treeWalker.nextNode()) {\n yield treeWalker.currentNode as T;\n }\n}\n\n/**\n * Iterates over `node` and its ancestors, crossing shadow DOM boundaries.\n *\n * Shadow roots are traversed through their host, so only elements are yielded.\n *\n * @example\n * ```typescript\n * for (const ancestor of iterAncestors(element)) { ... }\n * ```\n */\nexport function* iterAncestors(node?: Node | null): Generator<Element> {\n let current: Node | null | undefined = node;\n\n while (current) {\n if (isElement(current)) {\n yield current;\n }\n\n current = current instanceof ShadowRoot ? current.host : current.parentNode;\n }\n}\n\n/** Returns the root node (document or shadow root) of the given element. */\nexport function getRoot(\n element: Element,\n options?: GetRootNodeOptions\n): Document | ShadowRoot {\n return element.getRootNode(options) as Document | ShadowRoot;\n}\n\n/** Returns the element with the given id in the root node of `root`, if any. */\nexport function getElementByIdFromRoot(root: HTMLElement, id: string) {\n return getRoot(root).getElementById(id);\n}\n\nexport function isElement(node: unknown): node is Element {\n return node instanceof Node && node.nodeType === Node.ELEMENT_NODE;\n}\n\nexport function isDocument(node: unknown): node is Document {\n return node instanceof Node && node.nodeType === Node.DOCUMENT_NODE;\n}\n\n/** Returns the center x/y coordinate of a given element. */\nexport function getCenterPoint(element: Element): { x: number; y: number } {\n const { left, top, width, height } = element.getBoundingClientRect();\n\n return {\n x: left + width * 0.5,\n y: top + height * 0.5,\n };\n}\n\n/**\n * Maps a pointer's `clientX` coordinate to a fraction in the [0, 1] range of the\n * element's bounding box width, measured from the element's logical start edge -\n * the left edge when `ltr` is true, the right one otherwise.\n *\n * Returns 0 for an element without layout.\n *\n * @example\n * ```typescript\n * // Pointer 30px into a 120px wide element\n * pointToFraction(element, event.clientX); // 0.25\n * pointToFraction(element, event.clientX, false); // 0.75\n * ```\n */\nexport function pointToFraction(\n element: Element,\n clientX: number,\n ltr = true\n): number {\n const { left, right, width } = element.getBoundingClientRect();\n\n if (width === 0) {\n return 0;\n }\n\n return clamp((ltr ? clientX - left : right - clientX) / width, 0, 1);\n}\n\n/**\n * Concatenates the text content of the given nodes into a single string,\n * trimmed and with consecutive whitespace collapsed.\n *\n * Useful for deriving an accessible label from projected content.\n */\nexport function normalizedTextContent(nodes: Iterable<Node>): string {\n let text = '';\n\n for (const node of nodes) {\n text += node.textContent ?? '';\n }\n\n return text.trim().replace(/\\s+/gu, ' ');\n}\n\n/** Returns whether the given client coordinates lie within the bounding box of the element. */\nexport function isPointInsideElement(\n element: Element,\n x: number,\n y: number\n): boolean {\n const { left, right, top, bottom } = element.getBoundingClientRect();\n return (\n numberInRangeInclusive(x, left, right) &&\n numberInRangeInclusive(y, top, bottom)\n );\n}\n\n/** Returns the scale factor of a given element based on its bounding client rect and offset dimensions. */\nexport function getScaleFactor(element: HTMLElement): { x: number; y: number } {\n const { offsetWidth, offsetHeight } = element;\n const { width, height } = element.getBoundingClientRect();\n return { x: offsetWidth / width || 1, y: offsetHeight / height || 1 };\n}\n\n/** Rounds a CSS pixel value to the closest device-pixel boundary to avoid blurry rendering. */\nexport function roundByDPR(value: number): number {\n const dpr = globalThis.devicePixelRatio || 1;\n return Math.round(value * dpr) / dpr;\n}\n\n/** Null-safe `Element.scrollIntoView` defaulting to the nearest block/inline position. */\nexport function scrollIntoView(\n element?: HTMLElement | null,\n config?: ScrollIntoViewOptions\n): void {\n if (!element) {\n return;\n }\n\n element.scrollIntoView(\n Object.assign(\n {\n behavior: 'auto',\n block: 'nearest',\n inline: 'nearest',\n },\n config\n )\n );\n}\n\n/** Returns the default containing layer for floating elements such as drag and resize ghosts. */\nexport function getDefaultLayer(): HTMLElement {\n return document.body;\n}\n\n/** Applies the given CSS declarations to the inline style of the element. */\nexport function setStyles(\n element: HTMLElement,\n styles: Partial<CSSStyleDeclaration>\n): void {\n merge(element.style, styles);\n}\n\n/** Returns whether the given input has at least one selected file. */\nexport function hasFiles(input: { files: FileList | null }): boolean {\n return input.files != null && input.files.length > 0;\n}\n\n/**\n * Returns whether the given element is currently an open popover or not.\n * This is useful to determine if the popover is open without relying on the `open` property, which may not be in sync with the actual popover state if the opening/closing animations are still running.\n * Note: This function only works for elements that use the `:popover-open` pseudo-class to indicate\n */\nexport function isPopoverOpen(element?: Element): boolean {\n return element?.matches(':popover-open') ?? false;\n}\n\n/**\n * Returns whether the given element, or any of its ancestors across shadow DOM\n * boundaries, is positioned as `sticky`.\n */\nexport function hasStickyAncestor(element: Element): boolean {\n for (const ancestor of iterAncestors(element)) {\n if (getComputedStyle(ancestor).position === 'sticky') {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Returns the nearest visible ancestor of a given node, traversing through shadow DOM boundaries if necessary. If no visible ancestor is found, returns null.\n */\nexport function getVisibleAncestor(startNode: Node): HTMLElement | null {\n for (const ancestor of iterAncestors(startNode.parentNode)) {\n if (ancestor instanceof HTMLElement && ancestor.checkVisibility()) {\n return ancestor;\n }\n }\n\n return null;\n}\n"]}
|
|
@@ -19,6 +19,8 @@ export declare function getElementFromPath<K extends keyof HTMLElementTagNameMap
|
|
|
19
19
|
export declare function getElementFromPath<T extends Element>(predicate: string | ((element: Element) => boolean), event: Event): T | undefined;
|
|
20
20
|
/** Reusable event listener that just stops the propagation of the event. */
|
|
21
21
|
export declare function stopPropagation(event: Event): void;
|
|
22
|
+
/** Reusable event listener that just prevents the default action of the event. */
|
|
23
|
+
export declare function preventDefault(event: Event): void;
|
|
22
24
|
/**
|
|
23
25
|
* Returns whether focus has moved outside of the given host element for
|
|
24
26
|
* a `focusout`/`blur` event, that is the element gaining focus is not
|
|
@@ -10,6 +10,9 @@ export function getElementFromPath(predicate, event) {
|
|
|
10
10
|
export function stopPropagation(event) {
|
|
11
11
|
event.stopPropagation();
|
|
12
12
|
}
|
|
13
|
+
export function preventDefault(event) {
|
|
14
|
+
event.preventDefault();
|
|
15
|
+
}
|
|
13
16
|
export function focusLeftHost(host, event) {
|
|
14
17
|
return !host.contains(event.relatedTarget);
|
|
15
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/internals/utils/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA2B7D,MAAM,UAAU,kBAAkB,CAChC,SAAmD,EACnD,KAAY;IAEZ,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC;QAC9B,CAAC,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;QACtC,CAAC,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAEjC,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,IAAI,CAC7C,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CACjB,CAAC;AAC3B,CAAC;AAGD,MAAM,UAAU,eAAe,CAAC,KAAY;IAC1C,KAAK,CAAC,eAAe,EAAE,CAAC;AAC1B,CAAC;AAOD,MAAM,UAAU,aAAa,CAAC,IAAa,EAAE,KAAiB;IAC5D,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,aAA4B,CAAC,CAAC;AAC5D,CAAC;AAMD,MAAM,UAAU,oBAAoB,CAClC,OAAgB,EAChB,KAAa,EACb,QAA4C,EAC5C,OAA2C;IAE3C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,CAAC,GAAU,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;QAEhC,IAAI,CAAC,OAAO,EAAE,CAAC;YAEb,OAAO,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QAED,OAAO,qBAAqB,CAAC,OAAO,CAAC;YACnC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC;YAC1B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC,CAAC;IAEF,OAAO,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAWD,MAAM,UAAU,oBAAoB,CAGlC,MAAmB,EACnB,SAAY,EACZ,OAA2C,EAC3C,OAA2C;IAE3C,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE,CACpC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAuB,CAAC,CAAC;IAEhD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;AAC5D,CAAC","sourcesContent":["import { isServer } from 'lit';\nimport { isElement } from './dom.js';\nimport { isEventListenerObject, isString } from './types.js';\n\n/**\n * Finds the first element in the event's composed path that matches the provided predicate, which can be either a string selector or a function.\n *\n * @param predicate - A string representing a CSS selector or a function that takes an Element and returns a boolean indicating a match.\n * @param event - The event whose composed path will be searched for the matching element.\n * @returns The first Element that matches the predicate, or undefined if no match is found.\n *\n * @example\n * ```typescript\n * // Using a string selector\n * const button = getElementFromPath('button', event);\n * ```\n * ```typescript\n * // Using a predicate function\n * const customElement = getElementFromPath((el) => el.tagName === 'MY-ELEMENT', event);\n * ```\n */\nexport function getElementFromPath<K extends keyof HTMLElementTagNameMap>(\n predicate: K,\n event: Event\n): HTMLElementTagNameMap[K] | undefined;\nexport function getElementFromPath<T extends Element>(\n predicate: string | ((element: Element) => boolean),\n event: Event\n): T | undefined;\nexport function getElementFromPath(\n predicate: string | ((element: Element) => boolean),\n event: Event\n) {\n const func = isString(predicate)\n ? (e: Element) => e.matches(predicate)\n : (e: Element) => predicate(e);\n\n return Iterator.from(event.composedPath()).find(\n (item) => isElement(item) && func(item)\n ) as Element | undefined;\n}\n\n/** Reusable event listener that just stops the propagation of the event. */\nexport function stopPropagation(event: Event): void {\n event.stopPropagation();\n}\n\n/**\n * Returns whether focus has moved outside of the given host element for\n * a `focusout`/`blur` event, that is the element gaining focus is not\n * a descendant of the host.\n */\nexport function focusLeftHost(host: Element, event: FocusEvent): boolean {\n return !host.contains(event.relatedTarget as Node | null);\n}\n\n/**\n * Adds an event listener that holds only a weak reference to the passed\n * `listener`, thus not preventing it from being garbage collected.\n */\nexport function addWeakEventListener(\n element: Element,\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: AddEventListenerOptions | boolean\n): void {\n const weakRef = new WeakRef(listener);\n const wrapped = (evt: Event) => {\n const handler = weakRef.deref();\n\n if (!handler) {\n // The listener has been garbage collected - detach the wrapper as well\n element.removeEventListener(event, wrapped, options);\n return;\n }\n\n return isEventListenerObject(handler)\n ? handler.handleEvent(evt)\n : handler(evt);\n };\n\n element.addEventListener(event, wrapped, options);\n}\n\ntype EventTypeOf<T extends keyof HTMLElementEventMap | keyof WindowEventMap> =\n (HTMLElementEventMap & WindowEventMap)[T];\n\n/**\n * Safely adds an event listener to an HTMLElement, automatically handling\n * server-side rendering environments by doing nothing if `isServer` is true.\n * This function also correctly binds the `handler`'s `this` context to the `target` element\n * and ensures proper event type inference.\n */\nexport function addSafeEventListener<\n E extends keyof HTMLElementEventMap | keyof WindowEventMap,\n>(\n target: HTMLElement,\n eventName: E,\n handler: (event: EventTypeOf<E>) => unknown,\n options?: boolean | AddEventListenerOptions\n): void {\n if (isServer) {\n return;\n }\n\n const boundHandler = (event: Event) =>\n handler.call(target, event as EventTypeOf<E>);\n\n target.addEventListener(eventName, boundHandler, options);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../src/internals/utils/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AA2B7D,MAAM,UAAU,kBAAkB,CAChC,SAAmD,EACnD,KAAY;IAEZ,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC;QAC9B,CAAC,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;QACtC,CAAC,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAEjC,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,IAAI,CAC7C,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CACjB,CAAC;AAC3B,CAAC;AAGD,MAAM,UAAU,eAAe,CAAC,KAAY;IAC1C,KAAK,CAAC,eAAe,EAAE,CAAC;AAC1B,CAAC;AAGD,MAAM,UAAU,cAAc,CAAC,KAAY;IACzC,KAAK,CAAC,cAAc,EAAE,CAAC;AACzB,CAAC;AAOD,MAAM,UAAU,aAAa,CAAC,IAAa,EAAE,KAAiB;IAC5D,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,aAA4B,CAAC,CAAC;AAC5D,CAAC;AAMD,MAAM,UAAU,oBAAoB,CAClC,OAAgB,EAChB,KAAa,EACb,QAA4C,EAC5C,OAA2C;IAE3C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,CAAC,GAAU,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;QAEhC,IAAI,CAAC,OAAO,EAAE,CAAC;YAEb,OAAO,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QAED,OAAO,qBAAqB,CAAC,OAAO,CAAC;YACnC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC;YAC1B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC,CAAC;IAEF,OAAO,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAWD,MAAM,UAAU,oBAAoB,CAGlC,MAAmB,EACnB,SAAY,EACZ,OAA2C,EAC3C,OAA2C;IAE3C,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IAED,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE,CACpC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAuB,CAAC,CAAC;IAEhD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;AAC5D,CAAC","sourcesContent":["import { isServer } from 'lit';\nimport { isElement } from './dom.js';\nimport { isEventListenerObject, isString } from './types.js';\n\n/**\n * Finds the first element in the event's composed path that matches the provided predicate, which can be either a string selector or a function.\n *\n * @param predicate - A string representing a CSS selector or a function that takes an Element and returns a boolean indicating a match.\n * @param event - The event whose composed path will be searched for the matching element.\n * @returns The first Element that matches the predicate, or undefined if no match is found.\n *\n * @example\n * ```typescript\n * // Using a string selector\n * const button = getElementFromPath('button', event);\n * ```\n * ```typescript\n * // Using a predicate function\n * const customElement = getElementFromPath((el) => el.tagName === 'MY-ELEMENT', event);\n * ```\n */\nexport function getElementFromPath<K extends keyof HTMLElementTagNameMap>(\n predicate: K,\n event: Event\n): HTMLElementTagNameMap[K] | undefined;\nexport function getElementFromPath<T extends Element>(\n predicate: string | ((element: Element) => boolean),\n event: Event\n): T | undefined;\nexport function getElementFromPath(\n predicate: string | ((element: Element) => boolean),\n event: Event\n) {\n const func = isString(predicate)\n ? (e: Element) => e.matches(predicate)\n : (e: Element) => predicate(e);\n\n return Iterator.from(event.composedPath()).find(\n (item) => isElement(item) && func(item)\n ) as Element | undefined;\n}\n\n/** Reusable event listener that just stops the propagation of the event. */\nexport function stopPropagation(event: Event): void {\n event.stopPropagation();\n}\n\n/** Reusable event listener that just prevents the default action of the event. */\nexport function preventDefault(event: Event): void {\n event.preventDefault();\n}\n\n/**\n * Returns whether focus has moved outside of the given host element for\n * a `focusout`/`blur` event, that is the element gaining focus is not\n * a descendant of the host.\n */\nexport function focusLeftHost(host: Element, event: FocusEvent): boolean {\n return !host.contains(event.relatedTarget as Node | null);\n}\n\n/**\n * Adds an event listener that holds only a weak reference to the passed\n * `listener`, thus not preventing it from being garbage collected.\n */\nexport function addWeakEventListener(\n element: Element,\n event: string,\n listener: EventListenerOrEventListenerObject,\n options?: AddEventListenerOptions | boolean\n): void {\n const weakRef = new WeakRef(listener);\n const wrapped = (evt: Event) => {\n const handler = weakRef.deref();\n\n if (!handler) {\n // The listener has been garbage collected - detach the wrapper as well\n element.removeEventListener(event, wrapped, options);\n return;\n }\n\n return isEventListenerObject(handler)\n ? handler.handleEvent(evt)\n : handler(evt);\n };\n\n element.addEventListener(event, wrapped, options);\n}\n\ntype EventTypeOf<T extends keyof HTMLElementEventMap | keyof WindowEventMap> =\n (HTMLElementEventMap & WindowEventMap)[T];\n\n/**\n * Safely adds an event listener to an HTMLElement, automatically handling\n * server-side rendering environments by doing nothing if `isServer` is true.\n * This function also correctly binds the `handler`'s `this` context to the `target` element\n * and ensures proper event type inference.\n */\nexport function addSafeEventListener<\n E extends keyof HTMLElementEventMap | keyof WindowEventMap,\n>(\n target: HTMLElement,\n eventName: E,\n handler: (event: EventTypeOf<E>) => unknown,\n options?: boolean | AddEventListenerOptions\n): void {\n if (isServer) {\n return;\n }\n\n const boundHandler = (event: Event) =>\n handler.call(target, event as EventTypeOf<E>);\n\n target.addEventListener(eventName, boundHandler, options);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "igniteui-webcomponents",
|
|
3
|
-
"version": "7.3.
|
|
3
|
+
"version": "7.3.1",
|
|
4
4
|
"description": "Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.",
|
|
5
5
|
"author": "Infragistics",
|
|
6
6
|
"license": "MIT",
|