ngx-kit 9.2.2 → 9.2.4
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.
|
@@ -2804,6 +2804,7 @@ class NgxDraggable {
|
|
|
2804
2804
|
* When `true`, presses on native interactive controls (`button, a, input, textarea, select`,
|
|
2805
2805
|
* `[contenteditable]`) do not start a drag either. Off by default so that a page-builder canvas
|
|
2806
2806
|
* block can be grabbed by its own button/link, which is exactly what you want while editing.
|
|
2807
|
+
* @default false
|
|
2807
2808
|
*/
|
|
2808
2809
|
ignoreInteractive = input(false, /* @ts-ignore */
|
|
2809
2810
|
...(ngDevMode ? [{ debugName: "ignoreInteractive" }] : /* istanbul ignore next */ []));
|
|
@@ -2889,17 +2890,15 @@ class NgxDraggable {
|
|
|
2889
2890
|
this._ref.dropList?.removeItem(this._ref);
|
|
2890
2891
|
}
|
|
2891
2892
|
pointerDown(e) {
|
|
2892
|
-
if (this.disabled() ||
|
|
2893
|
-
e.button !== 0 ||
|
|
2894
|
-
this.isExcluded(e.target) ||
|
|
2895
|
-
!this.isOnHandle(e.target))
|
|
2893
|
+
if (this.disabled() || e.button !== 0 || !this.isOnHandle(e.target))
|
|
2896
2894
|
return;
|
|
2897
2895
|
// Nested draggables: pointerdown bubbles, so without this an ancestor draggable would start
|
|
2898
2896
|
// its own drag from the very same gesture. The innermost enabled draggable claims it.
|
|
2899
2897
|
if (claimedPointerEvents.has(e))
|
|
2900
2898
|
return;
|
|
2901
2899
|
claimedPointerEvents.add(e);
|
|
2902
|
-
|
|
2900
|
+
if (this.ignoreInteractive())
|
|
2901
|
+
e.preventDefault();
|
|
2903
2902
|
this.down = true;
|
|
2904
2903
|
this.keyboardDrag = false;
|
|
2905
2904
|
this.pointerId = e.pointerId;
|
|
@@ -3169,16 +3168,7 @@ class NgxDraggable {
|
|
|
3169
3168
|
if (!this.dragHandle())
|
|
3170
3169
|
return true;
|
|
3171
3170
|
// TODO notsafe instanseof: node.nodeType === Node.ELEMENT_NODE
|
|
3172
|
-
return isElementTarget(target) && !!target.closest(this.dragHandle());
|
|
3173
|
-
}
|
|
3174
|
-
/** Should a press on `target` be left alone (no drag)? */
|
|
3175
|
-
isExcluded(target) {
|
|
3176
|
-
if (!isElementTarget(target))
|
|
3177
|
-
return false;
|
|
3178
|
-
const selector = this.noDragSelector();
|
|
3179
|
-
if (selector && target.closest(selector))
|
|
3180
|
-
return true;
|
|
3181
|
-
return this.ignoreInteractive() && isEditableOrInteractive(target);
|
|
3171
|
+
return isElementTarget$1(target) && !!target.closest(this.dragHandle());
|
|
3182
3172
|
}
|
|
3183
3173
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxDraggable, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3184
3174
|
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.4", type: NgxDraggable, isStandalone: true, selector: "[NgxDraggable],[ngxDraggable]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, boundary: { classPropertyName: "boundary", publicName: "boundary", isSignal: true, isRequired: false, transformFunction: null }, dragRootElement: { classPropertyName: "dragRootElement", publicName: "dragRootElement", isSignal: true, isRequired: false, transformFunction: null }, dragHandle: { classPropertyName: "dragHandle", publicName: "dragHandle", isSignal: true, isRequired: false, transformFunction: null }, lockAxis: { classPropertyName: "lockAxis", publicName: "lockAxis", isSignal: true, isRequired: false, transformFunction: null }, dragThreshold: { classPropertyName: "dragThreshold", publicName: "dragThreshold", isSignal: true, isRequired: false, transformFunction: null }, keyboardStep: { classPropertyName: "keyboardStep", publicName: "keyboardStep", isSignal: true, isRequired: false, transformFunction: null }, autoScroll: { classPropertyName: "autoScroll", publicName: "autoScroll", isSignal: true, isRequired: false, transformFunction: null }, noDragSelector: { classPropertyName: "noDragSelector", publicName: "noDragSelector", isSignal: true, isRequired: false, transformFunction: null }, ignoreInteractive: { classPropertyName: "ignoreInteractive", publicName: "ignoreInteractive", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", dragRootElement: "dragRootElementChange", dragHandle: "dragHandleChange", dragStart: "dragStart", dragMove: "dragMove", dragEnd: "dragEnd" }, host: { properties: { "style.touch-action": "\"none\"", "attr.tabindex": "disabled() ? null : 0", "attr.aria-grabbed": "dragging()", "class.disable-drag": "disabled()" }, classAttribute: "ngx-draggable" }, providers: [{ provide: NGX_DRAGGABLE, useExisting: NgxDraggable }], queries: [{ propertyName: "customPreview", first: true, predicate: NgxDragPreview, descendants: true }], ngImport: i0 });
|
|
@@ -3203,15 +3193,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
3203
3193
|
type: ContentChild,
|
|
3204
3194
|
args: [NgxDragPreview]
|
|
3205
3195
|
}], dragStart: [{ type: i0.Output, args: ["dragStart"] }], dragMove: [{ type: i0.Output, args: ["dragMove"] }], dragEnd: [{ type: i0.Output, args: ["dragEnd"] }] } });
|
|
3206
|
-
function isEditableOrInteractive(el) {
|
|
3207
|
-
return !!el.closest('button,a[href],input,textarea,select,[contenteditable]:not([contenteditable="false"])');
|
|
3208
|
-
}
|
|
3209
3196
|
function isEditableTarget(target) {
|
|
3210
|
-
if (!isElementTarget(target))
|
|
3197
|
+
if (!isElementTarget$1(target))
|
|
3211
3198
|
return false;
|
|
3212
3199
|
return !!target.closest('input,textarea,select,[contenteditable]:not([contenteditable="false"])');
|
|
3213
3200
|
}
|
|
3214
|
-
function isElementTarget(target) {
|
|
3201
|
+
function isElementTarget$1(target) {
|
|
3215
3202
|
return (!!target &&
|
|
3216
3203
|
typeof target === 'object' &&
|
|
3217
3204
|
'nodeType' in target &&
|
|
@@ -3221,6 +3208,43 @@ function isElementTarget(target) {
|
|
|
3221
3208
|
|
|
3222
3209
|
const ALL_DIRECTIONS = ['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'];
|
|
3223
3210
|
const KEYBOARD_STEP = 8;
|
|
3211
|
+
/**
|
|
3212
|
+
* Elements matching this selector keep their normal pointer/touch behaviour.
|
|
3213
|
+
* Add data-ngx-resize-ignore to any custom interactive widget that should never
|
|
3214
|
+
* initiate resizing when it is close to the panel edge.
|
|
3215
|
+
*/
|
|
3216
|
+
const INTERACTIVE_SELECTOR = [
|
|
3217
|
+
'input',
|
|
3218
|
+
'textarea',
|
|
3219
|
+
'select',
|
|
3220
|
+
'option',
|
|
3221
|
+
'button',
|
|
3222
|
+
'a',
|
|
3223
|
+
'summary',
|
|
3224
|
+
'[contenteditable="true"]',
|
|
3225
|
+
'audio',
|
|
3226
|
+
'video',
|
|
3227
|
+
'iframe',
|
|
3228
|
+
'label',
|
|
3229
|
+
'[role="textbox"]',
|
|
3230
|
+
'[role="menuitem"]',
|
|
3231
|
+
'[role="tab"]',
|
|
3232
|
+
'mat-slider',
|
|
3233
|
+
'mat-select',
|
|
3234
|
+
'mat-checkbox',
|
|
3235
|
+
'mat-radio-button',
|
|
3236
|
+
'mat-slide-toggle',
|
|
3237
|
+
'.mat-mdc-slider',
|
|
3238
|
+
'.mat-mdc-select',
|
|
3239
|
+
'[role="button"]',
|
|
3240
|
+
'[role="slider"]',
|
|
3241
|
+
'[role="switch"]',
|
|
3242
|
+
'[role="checkbox"]',
|
|
3243
|
+
'[role="radio"]',
|
|
3244
|
+
'[role="combobox"]',
|
|
3245
|
+
'[role="listbox"]',
|
|
3246
|
+
'[data-ngx-resize-ignore]',
|
|
3247
|
+
].join(',');
|
|
3224
3248
|
class NgxResizable {
|
|
3225
3249
|
el;
|
|
3226
3250
|
disabled = model(false, /* @ts-ignore */
|
|
@@ -3250,14 +3274,16 @@ class NgxResizable {
|
|
|
3250
3274
|
...(ngDevMode ? [{ debugName: "resizing" }] : /* istanbul ignore next */ []));
|
|
3251
3275
|
direction = 'se';
|
|
3252
3276
|
start;
|
|
3253
|
-
pointer = {
|
|
3254
|
-
x: 0,
|
|
3255
|
-
y: 0,
|
|
3256
|
-
};
|
|
3277
|
+
pointer = { x: 0, y: 0 };
|
|
3257
3278
|
beforeTransition = '';
|
|
3258
3279
|
beforeWidth = '';
|
|
3259
3280
|
beforeHeight = '';
|
|
3260
|
-
|
|
3281
|
+
beforeTranslate = '';
|
|
3282
|
+
baseComputedTranslate = 'none';
|
|
3283
|
+
keyboardBaseTranslate = null;
|
|
3284
|
+
keyboardBaseInlineTranslate = '';
|
|
3285
|
+
startMatrix = { a: 1, b: 0, c: 0, d: 1 };
|
|
3286
|
+
pointerInverse = invertLinear({ a: 1, b: 0, c: 0, d: 1 });
|
|
3261
3287
|
pointerId = -1;
|
|
3262
3288
|
startWidth = 0;
|
|
3263
3289
|
startHeight = 0;
|
|
@@ -3273,47 +3299,43 @@ class NgxResizable {
|
|
|
3273
3299
|
}
|
|
3274
3300
|
}
|
|
3275
3301
|
onPointerDown(e) {
|
|
3276
|
-
if (this.disabled() || e.button !== 0)
|
|
3302
|
+
if (this.disabled() || e.button !== 0 || this.resizing())
|
|
3277
3303
|
return;
|
|
3278
|
-
}
|
|
3279
3304
|
const dir = this.hitDirection(e);
|
|
3280
|
-
if (
|
|
3305
|
+
if (dir)
|
|
3306
|
+
this.beginResize(e, dir);
|
|
3307
|
+
}
|
|
3308
|
+
/** Entry point used by the typed NgxResizeHandle directive. */
|
|
3309
|
+
beginResize(e, direction) {
|
|
3310
|
+
if (this.disabled() || e.button !== 0 || this.resizing())
|
|
3311
|
+
return;
|
|
3312
|
+
const dir = resolveLogicalDirection(direction, isRtl(this.el.nativeElement));
|
|
3313
|
+
if (!this.resolvedDirections().includes(dir))
|
|
3281
3314
|
return;
|
|
3282
|
-
}
|
|
3283
3315
|
e.preventDefault();
|
|
3284
|
-
e.stopPropagation();
|
|
3285
|
-
e.stopImmediatePropagation();
|
|
3286
3316
|
const element = this.el.nativeElement;
|
|
3287
3317
|
this.direction = dir;
|
|
3288
3318
|
this.pointerId = e.pointerId;
|
|
3289
|
-
/**
|
|
3290
|
-
* This is the actual visual rectangle.
|
|
3291
|
-
* It already contains any transform created by DragRef.
|
|
3292
|
-
*/
|
|
3293
3319
|
this.start = element.getBoundingClientRect();
|
|
3294
|
-
this.pointer = {
|
|
3295
|
-
x: e.clientX,
|
|
3296
|
-
y: e.clientY,
|
|
3297
|
-
};
|
|
3320
|
+
this.pointer = { x: e.clientX, y: e.clientY };
|
|
3298
3321
|
this.beforeTransition = element.style.transition;
|
|
3299
3322
|
this.beforeWidth = element.style.width;
|
|
3300
3323
|
this.beforeHeight = element.style.height;
|
|
3301
|
-
this.
|
|
3302
|
-
this.
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
this.beforeTransform = element.style.transform;
|
|
3324
|
+
this.beforeTranslate = element.style.translate;
|
|
3325
|
+
this.baseComputedTranslate =
|
|
3326
|
+
element.ownerDocument.defaultView?.getComputedStyle(element).translate ?? 'none';
|
|
3327
|
+
this.keyboardBaseTranslate = null;
|
|
3328
|
+
this.startMatrix = getLocalToViewportMatrix(element);
|
|
3329
|
+
this.pointerInverse = invertLinear(this.startMatrix);
|
|
3330
|
+
this.startWidth = readBorderBoxSize(element, 'x');
|
|
3331
|
+
this.startHeight = readBorderBoxSize(element, 'y');
|
|
3310
3332
|
this.resizing.set(true);
|
|
3311
3333
|
element.style.transition = 'none';
|
|
3312
3334
|
try {
|
|
3313
3335
|
element.setPointerCapture?.(e.pointerId);
|
|
3314
3336
|
}
|
|
3315
3337
|
catch {
|
|
3316
|
-
|
|
3338
|
+
// Document listeners remain as a fallback.
|
|
3317
3339
|
}
|
|
3318
3340
|
const doc = element.ownerDocument;
|
|
3319
3341
|
this.removeDocumentListeners = [
|
|
@@ -3328,29 +3350,23 @@ class NgxResizable {
|
|
|
3328
3350
|
this.resizeStart.emit(out);
|
|
3329
3351
|
}
|
|
3330
3352
|
onPointerMove(e) {
|
|
3331
|
-
if (!this.resizing() || e.pointerId !== this.pointerId)
|
|
3353
|
+
if (!this.resizing() || e.pointerId !== this.pointerId)
|
|
3332
3354
|
return;
|
|
3333
|
-
}
|
|
3334
3355
|
const out = this.calculate(e);
|
|
3335
3356
|
this.apply(out);
|
|
3336
3357
|
this.resizeMove.emit(out);
|
|
3337
3358
|
}
|
|
3338
3359
|
onPointerUp(e) {
|
|
3339
|
-
if (!this.resizing() || e.pointerId !== this.pointerId)
|
|
3360
|
+
if (!this.resizing() || e.pointerId !== this.pointerId)
|
|
3340
3361
|
return;
|
|
3341
|
-
}
|
|
3342
3362
|
const out = this.calculate(e);
|
|
3343
3363
|
this.apply(out);
|
|
3344
3364
|
this.resizeEnd.emit(out);
|
|
3345
3365
|
this.finish();
|
|
3346
3366
|
}
|
|
3347
3367
|
onDocumentKeyDown(e) {
|
|
3348
|
-
if (!this.resizing())
|
|
3368
|
+
if (!this.resizing() || e.key !== 'Escape')
|
|
3349
3369
|
return;
|
|
3350
|
-
}
|
|
3351
|
-
if (e.key !== 'Escape') {
|
|
3352
|
-
return;
|
|
3353
|
-
}
|
|
3354
3370
|
e.preventDefault();
|
|
3355
3371
|
this.restoreBeforeResize();
|
|
3356
3372
|
this.finish();
|
|
@@ -3365,115 +3381,187 @@ class NgxResizable {
|
|
|
3365
3381
|
const element = this.el.nativeElement;
|
|
3366
3382
|
element.style.width = this.beforeWidth;
|
|
3367
3383
|
element.style.height = this.beforeHeight;
|
|
3368
|
-
element.style.
|
|
3384
|
+
element.style.translate = this.beforeTranslate;
|
|
3369
3385
|
}
|
|
3386
|
+
/**
|
|
3387
|
+
* Keyboard resizing respects the configured directions.
|
|
3388
|
+
* The arrow keys move the active physical edge:
|
|
3389
|
+
* - if only west is enabled, horizontal keys operate on west;
|
|
3390
|
+
* - if only east is enabled, horizontal keys operate on east;
|
|
3391
|
+
* - north/south follow the same rule vertically.
|
|
3392
|
+
* Disabled axes are never modified.
|
|
3393
|
+
*/
|
|
3370
3394
|
onHandleKeyDown(e) {
|
|
3371
|
-
if (this.disabled())
|
|
3395
|
+
if (this.disabled() || this.resizing())
|
|
3372
3396
|
return;
|
|
3373
|
-
|
|
3374
|
-
// Only when the resizable element itself is focused: arrow keys pressed inside an input /
|
|
3375
|
-
// contenteditable that lives in the block are caret movement, not a resize request.
|
|
3376
|
-
if (e.target !== this.el.nativeElement) {
|
|
3397
|
+
if (e.target !== this.el.nativeElement)
|
|
3377
3398
|
return;
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
const
|
|
3399
|
+
if (this.isEditableTarget(e.target))
|
|
3400
|
+
return;
|
|
3401
|
+
const allowed = this.resolvedDirections();
|
|
3402
|
+
const horizontalEdge = this.chooseAxisEdge(allowed, 'x', e.key);
|
|
3403
|
+
const verticalEdge = this.chooseAxisEdge(allowed, 'y', e.key);
|
|
3381
3404
|
let dw = 0;
|
|
3382
3405
|
let dh = 0;
|
|
3383
|
-
|
|
3384
|
-
|
|
3406
|
+
const configuredStep = this.keyboardStep();
|
|
3407
|
+
const step = (Number.isFinite(configuredStep) ? Math.max(1, configuredStep) : KEYBOARD_STEP) *
|
|
3408
|
+
(e.shiftKey ? 4 : 1);
|
|
3409
|
+
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
|
|
3410
|
+
if (!horizontalEdge)
|
|
3411
|
+
return;
|
|
3412
|
+
const positive = e.key === 'ArrowRight';
|
|
3413
|
+
const rtl = isRtl(this.el.nativeElement);
|
|
3414
|
+
const physicalDelta = (positive ? 1 : -1) * (rtl ? -1 : 1);
|
|
3415
|
+
// East edge follows pointer direction; west edge moves the opposite way
|
|
3416
|
+
// relative to the resulting width.
|
|
3417
|
+
dw = horizontalEdge === 'e' ? physicalDelta * step : -physicalDelta * step;
|
|
3418
|
+
}
|
|
3419
|
+
else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
|
|
3420
|
+
if (!verticalEdge)
|
|
3421
|
+
return;
|
|
3422
|
+
const physicalDelta = e.key === 'ArrowDown' ? 1 : -1;
|
|
3423
|
+
dh = verticalEdge === 's' ? physicalDelta * step : -physicalDelta * step;
|
|
3385
3424
|
}
|
|
3386
|
-
else
|
|
3387
|
-
|
|
3425
|
+
else {
|
|
3426
|
+
return;
|
|
3388
3427
|
}
|
|
3389
|
-
|
|
3390
|
-
|
|
3428
|
+
e.preventDefault();
|
|
3429
|
+
const element = this.el.nativeElement;
|
|
3430
|
+
const oldWidth = readBorderBoxSize(element, 'x');
|
|
3431
|
+
const oldHeight = readBorderBoxSize(element, 'y');
|
|
3432
|
+
let width = oldWidth;
|
|
3433
|
+
let height = oldHeight;
|
|
3434
|
+
if (dw !== 0) {
|
|
3435
|
+
width = this.clampSize(oldWidth + dw, 'x');
|
|
3436
|
+
}
|
|
3437
|
+
if (dh !== 0) {
|
|
3438
|
+
height = this.clampSize(oldHeight + dh, 'y');
|
|
3439
|
+
}
|
|
3440
|
+
// Keep the opposite edge fixed for west/north keyboard resizing.
|
|
3441
|
+
const rect = element.getBoundingClientRect();
|
|
3442
|
+
const matrix = getLocalToViewportMatrix(element);
|
|
3443
|
+
const scaleX = Math.hypot(matrix.a, matrix.b) || 1;
|
|
3444
|
+
const scaleY = Math.hypot(matrix.c, matrix.d) || 1;
|
|
3445
|
+
let moveLeft = horizontalEdge === 'w' ? (oldWidth - width) * scaleX : 0;
|
|
3446
|
+
let moveTop = verticalEdge === 'n' ? (oldHeight - height) * scaleY : 0;
|
|
3447
|
+
const boundary = this.boundary();
|
|
3448
|
+
if (boundary) {
|
|
3449
|
+
const clamped = clampResizeWithinBoundary(boundary.getBoundingClientRect(), rect, width * scaleX, height * scaleY, moveLeft, moveTop);
|
|
3450
|
+
width = clamped.width / scaleX;
|
|
3451
|
+
height = clamped.height / scaleY;
|
|
3452
|
+
moveLeft = clamped.left;
|
|
3453
|
+
moveTop = clamped.top;
|
|
3391
3454
|
}
|
|
3392
|
-
|
|
3393
|
-
|
|
3455
|
+
// Keyboard resize keeps a stable base translation and recomputes the total offset
|
|
3456
|
+
// on every key press. This prevents an ever-growing chain of calc()/translate values.
|
|
3457
|
+
if (this.keyboardBaseTranslate === null) {
|
|
3458
|
+
const computed = element.ownerDocument.defaultView?.getComputedStyle(element);
|
|
3459
|
+
this.keyboardBaseTranslate = computed?.translate ?? 'none';
|
|
3460
|
+
this.keyboardBaseInlineTranslate = element.style.translate;
|
|
3461
|
+
}
|
|
3462
|
+
const style = this.toStyleSize(width, height);
|
|
3463
|
+
element.style.width = `${style.width}px`;
|
|
3464
|
+
element.style.height = `${style.height}px`;
|
|
3465
|
+
element.style.translate = this.keyboardBaseInlineTranslate;
|
|
3466
|
+
// Keep the opposite edge fixed without touching `transform` (owned by NgxDraggable).
|
|
3467
|
+
const current = element.getBoundingClientRect();
|
|
3468
|
+
const correctionX = rect.left + moveLeft - current.left;
|
|
3469
|
+
const correctionY = rect.top + moveTop - current.top;
|
|
3470
|
+
if (correctionX || correctionY) {
|
|
3471
|
+
const local = viewportDeltaToLocal(element, { x: correctionX, y: correctionY });
|
|
3472
|
+
writeTranslateWithOffset(element, this.keyboardBaseTranslate, local);
|
|
3394
3473
|
}
|
|
3395
3474
|
else {
|
|
3396
|
-
|
|
3475
|
+
element.style.translate = this.keyboardBaseInlineTranslate;
|
|
3397
3476
|
}
|
|
3398
|
-
e.preventDefault();
|
|
3399
|
-
const rect = this.el.nativeElement.getBoundingClientRect();
|
|
3400
|
-
const width = this.clampGrid(Math.max(this.minWidth(), Math.min(this.maxWidth(), this.el.nativeElement.offsetWidth + dw)), 'x');
|
|
3401
|
-
const height = this.clampGrid(Math.max(this.minHeight(), Math.min(this.maxHeight(), this.el.nativeElement.offsetHeight + dh)), 'y');
|
|
3402
|
-
const styled = this.toStyleSize(width, height);
|
|
3403
|
-
this.el.nativeElement.style.width = `${styled.width}px`;
|
|
3404
|
-
this.el.nativeElement.style.height = `${styled.height}px`;
|
|
3405
3477
|
const out = {
|
|
3406
3478
|
width,
|
|
3407
3479
|
height,
|
|
3408
|
-
moveLeft
|
|
3409
|
-
moveTop
|
|
3410
|
-
left: rect.left,
|
|
3411
|
-
top: rect.top,
|
|
3412
|
-
direction:
|
|
3480
|
+
moveLeft,
|
|
3481
|
+
moveTop,
|
|
3482
|
+
left: rect.left + moveLeft,
|
|
3483
|
+
top: rect.top + moveTop,
|
|
3484
|
+
direction: this.keyboardDirection(horizontalEdge, verticalEdge),
|
|
3413
3485
|
};
|
|
3486
|
+
this.resizeStart.emit(out);
|
|
3414
3487
|
this.resizeMove.emit(out);
|
|
3415
3488
|
this.resizeEnd.emit(out);
|
|
3416
3489
|
}
|
|
3490
|
+
chooseAxisEdge(allowed, axis, key) {
|
|
3491
|
+
if (axis === 'x') {
|
|
3492
|
+
const hasWest = allowed.some((d) => d.includes('w'));
|
|
3493
|
+
const hasEast = allowed.some((d) => d.includes('e'));
|
|
3494
|
+
if (key === 'ArrowLeft') {
|
|
3495
|
+
if (hasWest)
|
|
3496
|
+
return 'w';
|
|
3497
|
+
if (hasEast)
|
|
3498
|
+
return 'e';
|
|
3499
|
+
}
|
|
3500
|
+
if (key === 'ArrowRight') {
|
|
3501
|
+
if (hasEast)
|
|
3502
|
+
return 'e';
|
|
3503
|
+
if (hasWest)
|
|
3504
|
+
return 'w';
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
else {
|
|
3508
|
+
const hasNorth = allowed.some((d) => d.includes('n'));
|
|
3509
|
+
const hasSouth = allowed.some((d) => d.includes('s'));
|
|
3510
|
+
if (key === 'ArrowUp') {
|
|
3511
|
+
if (hasNorth)
|
|
3512
|
+
return 'n';
|
|
3513
|
+
if (hasSouth)
|
|
3514
|
+
return 's';
|
|
3515
|
+
}
|
|
3516
|
+
if (key === 'ArrowDown') {
|
|
3517
|
+
if (hasSouth)
|
|
3518
|
+
return 's';
|
|
3519
|
+
if (hasNorth)
|
|
3520
|
+
return 'n';
|
|
3521
|
+
}
|
|
3522
|
+
}
|
|
3523
|
+
return null;
|
|
3524
|
+
}
|
|
3525
|
+
keyboardDirection(horizontal, vertical) {
|
|
3526
|
+
if (horizontal && vertical)
|
|
3527
|
+
return `${vertical}${horizontal}`;
|
|
3528
|
+
return horizontal ?? vertical ?? 'se';
|
|
3529
|
+
}
|
|
3530
|
+
isEditableTarget(target) {
|
|
3531
|
+
if (!isElementTarget(target))
|
|
3532
|
+
return false;
|
|
3533
|
+
return !!target.closest(INTERACTIVE_SELECTOR);
|
|
3534
|
+
}
|
|
3417
3535
|
calculate(e) {
|
|
3418
|
-
const
|
|
3536
|
+
const delta = applyLinear(this.pointerInverse, {
|
|
3419
3537
|
x: e.clientX - this.pointer.x,
|
|
3420
3538
|
y: e.clientY - this.pointer.y,
|
|
3421
3539
|
});
|
|
3422
|
-
const dx = localDelta.x;
|
|
3423
|
-
const dy = localDelta.y;
|
|
3424
3540
|
let width = this.startWidth;
|
|
3425
3541
|
let height = this.startHeight;
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
/**
|
|
3439
|
-
* South
|
|
3440
|
-
*/
|
|
3441
|
-
if (this.direction.includes('s')) {
|
|
3442
|
-
height += dy;
|
|
3443
|
-
}
|
|
3444
|
-
/**
|
|
3445
|
-
* North
|
|
3446
|
-
*/
|
|
3447
|
-
if (this.direction.includes('n')) {
|
|
3448
|
-
height -= dy;
|
|
3449
|
-
}
|
|
3450
|
-
width = this.clampGrid(Math.max(this.minWidth(), Math.min(this.maxWidth(), width)), 'x');
|
|
3451
|
-
height = this.clampGrid(Math.max(this.minHeight(), Math.min(this.maxHeight(), height)), 'y');
|
|
3452
|
-
/**
|
|
3453
|
-
* Calculate the intended visual position.
|
|
3454
|
-
*
|
|
3455
|
-
* This is useful for boundary calculations and
|
|
3456
|
-
* emitted resize events.
|
|
3457
|
-
*/
|
|
3458
|
-
const matrix = getLocalToViewportMatrix(this.el.nativeElement);
|
|
3459
|
-
const scaleX = Math.hypot(matrix.a, matrix.b) || 1;
|
|
3460
|
-
const scaleY = Math.hypot(matrix.c, matrix.d) || 1;
|
|
3542
|
+
if (this.direction.includes('e'))
|
|
3543
|
+
width += delta.x;
|
|
3544
|
+
if (this.direction.includes('w'))
|
|
3545
|
+
width -= delta.x;
|
|
3546
|
+
if (this.direction.includes('s'))
|
|
3547
|
+
height += delta.y;
|
|
3548
|
+
if (this.direction.includes('n'))
|
|
3549
|
+
height -= delta.y;
|
|
3550
|
+
width = this.clampSize(width, 'x');
|
|
3551
|
+
height = this.clampSize(height, 'y');
|
|
3552
|
+
const scaleX = Math.hypot(this.startMatrix.a, this.startMatrix.b) || 1;
|
|
3553
|
+
const scaleY = Math.hypot(this.startMatrix.c, this.startMatrix.d) || 1;
|
|
3461
3554
|
let left = this.start.left;
|
|
3462
3555
|
let top = this.start.top;
|
|
3463
|
-
if (this.direction.includes('w'))
|
|
3556
|
+
if (this.direction.includes('w'))
|
|
3464
3557
|
left = this.start.right - width * scaleX;
|
|
3465
|
-
|
|
3466
|
-
if (this.direction.includes('n')) {
|
|
3558
|
+
if (this.direction.includes('n'))
|
|
3467
3559
|
top = this.start.bottom - height * scaleY;
|
|
3468
|
-
}
|
|
3469
3560
|
let moveLeft = left - this.start.left;
|
|
3470
3561
|
let moveTop = top - this.start.top;
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
const boundaryEl = this.boundary();
|
|
3475
|
-
if (boundaryEl) {
|
|
3476
|
-
const clamped = clampResizeWithinBoundary(boundaryEl.getBoundingClientRect(), this.start, width * scaleX, height * scaleY, moveLeft, moveTop);
|
|
3562
|
+
const boundary = this.boundary();
|
|
3563
|
+
if (boundary) {
|
|
3564
|
+
const clamped = clampResizeWithinBoundary(boundary.getBoundingClientRect(), this.start, width * scaleX, height * scaleY, moveLeft, moveTop);
|
|
3477
3565
|
width = clamped.width / scaleX;
|
|
3478
3566
|
height = clamped.height / scaleY;
|
|
3479
3567
|
moveLeft = clamped.left;
|
|
@@ -3493,63 +3581,22 @@ class NgxResizable {
|
|
|
3493
3581
|
}
|
|
3494
3582
|
apply(out) {
|
|
3495
3583
|
const element = this.el.nativeElement;
|
|
3496
|
-
|
|
3497
|
-
* Always reset to the transform that existed before
|
|
3498
|
-
* this resize operation started.
|
|
3499
|
-
*
|
|
3500
|
-
* This prevents resize corrections from accumulating.
|
|
3501
|
-
*/
|
|
3502
|
-
element.style.transform = this.beforeTransform;
|
|
3503
|
-
/**
|
|
3504
|
-
* Apply the actual size first.
|
|
3505
|
-
*
|
|
3506
|
-
* Changing width/height may cause the browser to re-layout
|
|
3507
|
-
* the element, especially for relative/flex/grid/static layouts.
|
|
3508
|
-
*/
|
|
3584
|
+
element.style.translate = this.beforeTranslate;
|
|
3509
3585
|
const style = this.toStyleSize(out.width, out.height);
|
|
3510
3586
|
element.style.width = `${style.width}px`;
|
|
3511
3587
|
element.style.height = `${style.height}px`;
|
|
3512
|
-
/**
|
|
3513
|
-
* Force/read layout after changing the size.
|
|
3514
|
-
*/
|
|
3515
3588
|
const current = element.getBoundingClientRect();
|
|
3516
|
-
/**
|
|
3517
|
-
* These are the positions where the element MUST visually be.
|
|
3518
|
-
*
|
|
3519
|
-
* `out.moveLeft` / `out.moveTop` are calculated in `calculate()`
|
|
3520
|
-
* from the original visual rectangle.
|
|
3521
|
-
*/
|
|
3522
3589
|
const targetLeft = this.start.left + out.moveLeft;
|
|
3523
3590
|
const targetTop = this.start.top + out.moveTop;
|
|
3524
|
-
/**
|
|
3525
|
-
* Browser's actual position after width/height changed.
|
|
3526
|
-
*
|
|
3527
|
-
* The difference between target and current position is the
|
|
3528
|
-
* correction that must be applied using transform.
|
|
3529
|
-
*/
|
|
3530
3591
|
const correctionX = targetLeft - current.left;
|
|
3531
3592
|
const correctionY = targetTop - current.top;
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
element.style.transform = this.beforeTransform;
|
|
3593
|
+
if (!correctionX && !correctionY) {
|
|
3594
|
+
element.style.translate = this.beforeTranslate;
|
|
3535
3595
|
return;
|
|
3536
3596
|
}
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
* correction required by Resize.
|
|
3540
|
-
*/
|
|
3541
|
-
const baseTransform = this.beforeTransform && this.beforeTransform !== 'none' ? `${this.beforeTransform} ` : '';
|
|
3542
|
-
const localCorrection = viewportDeltaToLocal(element, { x: correctionX, y: correctionY });
|
|
3543
|
-
element.style.transform =
|
|
3544
|
-
`${baseTransform}translate3d(` + `${localCorrection.x}px, ` + `${localCorrection.y}px, 0)`;
|
|
3597
|
+
const local = viewportDeltaToLocal(element, { x: correctionX, y: correctionY });
|
|
3598
|
+
writeTranslateWithOffset(element, this.baseComputedTranslate, local);
|
|
3545
3599
|
}
|
|
3546
|
-
/**
|
|
3547
|
-
* `offsetWidth/Height` (what we measure and report) are BORDER-box sizes. The inline
|
|
3548
|
-
* `width/height` we write are interpreted according to `box-sizing`: for the CSS default
|
|
3549
|
-
* (`content-box`) writing the border-box number would make a padded/bordered block jump by
|
|
3550
|
-
* its padding+border the instant a resize starts. Convert so the box is exactly the size
|
|
3551
|
-
* reported in `IResizableOutput`.
|
|
3552
|
-
*/
|
|
3553
3600
|
toStyleSize(width, height) {
|
|
3554
3601
|
const el = this.el.nativeElement;
|
|
3555
3602
|
const cs = el.ownerDocument.defaultView?.getComputedStyle(el);
|
|
@@ -3558,17 +3605,25 @@ class NgxResizable {
|
|
|
3558
3605
|
const px = (v) => Number.parseFloat(v) || 0;
|
|
3559
3606
|
const extraX = px(cs.paddingLeft) + px(cs.paddingRight) + px(cs.borderLeftWidth) + px(cs.borderRightWidth);
|
|
3560
3607
|
const extraY = px(cs.paddingTop) + px(cs.paddingBottom) + px(cs.borderTopWidth) + px(cs.borderBottomWidth);
|
|
3561
|
-
return {
|
|
3608
|
+
return {
|
|
3609
|
+
width: Math.max(0, width - extraX),
|
|
3610
|
+
height: Math.max(0, height - extraY),
|
|
3611
|
+
};
|
|
3562
3612
|
}
|
|
3563
|
-
|
|
3564
|
-
const
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
const
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3613
|
+
clampSize(value, axis) {
|
|
3614
|
+
const minInput = axis === 'x' ? this.minWidth() : this.minHeight();
|
|
3615
|
+
const maxInput = axis === 'x' ? this.maxWidth() : this.maxHeight();
|
|
3616
|
+
const min = Number.isFinite(minInput) ? Math.max(0, minInput) : 0;
|
|
3617
|
+
const max = Number.isFinite(maxInput) ? Math.max(min, maxInput) : Infinity;
|
|
3618
|
+
const bounded = Math.min(max, Math.max(min, Number.isFinite(value) ? value : min));
|
|
3619
|
+
const grid = this.grid();
|
|
3620
|
+
const step = typeof grid === 'number' ? grid : grid?.[axis];
|
|
3621
|
+
if (!step || !Number.isFinite(step) || step <= 0)
|
|
3622
|
+
return bounded;
|
|
3623
|
+
// Snap relative to the minimum, then clamp again so grid rounding can never
|
|
3624
|
+
// violate the configured min/max constraints.
|
|
3625
|
+
const snapped = min + Math.round((bounded - min) / step) * step;
|
|
3626
|
+
return Math.min(max, Math.max(min, snapped));
|
|
3572
3627
|
}
|
|
3573
3628
|
finish() {
|
|
3574
3629
|
this.resizing.set(false);
|
|
@@ -3584,9 +3639,12 @@ class NgxResizable {
|
|
|
3584
3639
|
}
|
|
3585
3640
|
}
|
|
3586
3641
|
catch {
|
|
3587
|
-
|
|
3642
|
+
// Pointer capture may already have been released.
|
|
3588
3643
|
}
|
|
3589
|
-
this.
|
|
3644
|
+
this.beforeTranslate = '';
|
|
3645
|
+
this.baseComputedTranslate = 'none';
|
|
3646
|
+
this.keyboardBaseTranslate = null;
|
|
3647
|
+
this.keyboardBaseInlineTranslate = '';
|
|
3590
3648
|
}
|
|
3591
3649
|
resolvedDirections() {
|
|
3592
3650
|
const rtl = isRtl(this.el.nativeElement);
|
|
@@ -3598,68 +3656,59 @@ class NgxResizable {
|
|
|
3598
3656
|
}
|
|
3599
3657
|
hitDirection(e) {
|
|
3600
3658
|
const element = this.el.nativeElement;
|
|
3601
|
-
const
|
|
3602
|
-
|
|
3603
|
-
const
|
|
3604
|
-
|
|
3605
|
-
const isTop = e.clientY - rect.top <= edge;
|
|
3606
|
-
const isBottom = rect.bottom - e.clientY <= edge;
|
|
3607
|
-
/**
|
|
3608
|
-
* Explicit resize handle has priority.
|
|
3609
|
-
*/
|
|
3610
|
-
// TODO notsafe instanceof:node.nodeType === Node.ELEMENT_NODE
|
|
3611
|
-
const handle = isHTMLElementTarget(e.target)
|
|
3612
|
-
? e.target.closest('[data-ngx-resize-handle]')
|
|
3659
|
+
const target = e.target;
|
|
3660
|
+
// Explicit handles are allowed even when they are inside the panel.
|
|
3661
|
+
const handle = isElementTarget(target)
|
|
3662
|
+
? target.closest('[data-ngx-resize-handle]')
|
|
3613
3663
|
: null;
|
|
3614
3664
|
if (handle && element.contains(handle)) {
|
|
3615
3665
|
const raw = handle.dataset['ngxResizeHandle'];
|
|
3616
|
-
if (!raw)
|
|
3666
|
+
if (!raw)
|
|
3617
3667
|
return null;
|
|
3618
|
-
}
|
|
3619
3668
|
const resolved = resolveLogicalDirection(raw, isRtl(element));
|
|
3620
3669
|
return this.resolvedDirections().includes(resolved) ? resolved : null;
|
|
3621
3670
|
}
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
*
|
|
3625
|
-
* left -> w
|
|
3626
|
-
* right -> e
|
|
3627
|
-
*
|
|
3628
|
-
* RTL is handled only when a logical direction
|
|
3629
|
-
* such as "start" / "end" is requested.
|
|
3630
|
-
*/
|
|
3631
|
-
const direction = isTop && isLeft
|
|
3632
|
-
? 'nw'
|
|
3633
|
-
: isTop && isRight
|
|
3634
|
-
? 'ne'
|
|
3635
|
-
: isBottom && isLeft
|
|
3636
|
-
? 'sw'
|
|
3637
|
-
: isBottom && isRight
|
|
3638
|
-
? 'se'
|
|
3639
|
-
: isTop
|
|
3640
|
-
? 'n'
|
|
3641
|
-
: isRight
|
|
3642
|
-
? 'e'
|
|
3643
|
-
: isBottom
|
|
3644
|
-
? 's'
|
|
3645
|
-
: isLeft
|
|
3646
|
-
? 'w'
|
|
3647
|
-
: null;
|
|
3648
|
-
if (!direction) {
|
|
3671
|
+
// Never steal pointer events from nested interactive controls.
|
|
3672
|
+
if (isElementTarget(target) && target.closest(INTERACTIVE_SELECTOR))
|
|
3649
3673
|
return null;
|
|
3650
|
-
|
|
3651
|
-
|
|
3674
|
+
const rect = element.getBoundingClientRect();
|
|
3675
|
+
const edge = Math.min(12, Math.max(6, Math.min(rect.width, rect.height) * 0.18));
|
|
3676
|
+
const isLeft = e.clientX - rect.left <= edge;
|
|
3677
|
+
const isRight = rect.right - e.clientX <= edge;
|
|
3678
|
+
const isTop = e.clientY - rect.top <= edge;
|
|
3679
|
+
const isBottom = rect.bottom - e.clientY <= edge;
|
|
3680
|
+
const candidates = [];
|
|
3681
|
+
if (isTop && isLeft)
|
|
3682
|
+
candidates.push('nw', 'n', 'w');
|
|
3683
|
+
else if (isTop && isRight)
|
|
3684
|
+
candidates.push('ne', 'n', 'e');
|
|
3685
|
+
else if (isBottom && isLeft)
|
|
3686
|
+
candidates.push('sw', 's', 'w');
|
|
3687
|
+
else if (isBottom && isRight)
|
|
3688
|
+
candidates.push('se', 's', 'e');
|
|
3689
|
+
else if (isTop)
|
|
3690
|
+
candidates.push('n');
|
|
3691
|
+
else if (isRight)
|
|
3692
|
+
candidates.push('e');
|
|
3693
|
+
else if (isBottom)
|
|
3694
|
+
candidates.push('s');
|
|
3695
|
+
else if (isLeft)
|
|
3696
|
+
candidates.push('w');
|
|
3697
|
+
const allowed = new Set(this.resolvedDirections());
|
|
3698
|
+
return candidates.find((candidate) => allowed.has(candidate)) ?? null;
|
|
3652
3699
|
}
|
|
3653
3700
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxResizable, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3654
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.4", type: NgxResizable, isStandalone: true, selector: "[NgxResizable],[ngxResizable]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, directions: { classPropertyName: "directions", publicName: "directions", isSignal: true, isRequired: false, transformFunction: null }, grid: { classPropertyName: "grid", publicName: "grid", isSignal: true, isRequired: false, transformFunction: null }, boundary: { classPropertyName: "boundary", publicName: "boundary", isSignal: true, isRequired: false, transformFunction: null }, keyboardStep: { classPropertyName: "keyboardStep", publicName: "keyboardStep", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", minWidth: "minWidthChange", minHeight: "minHeightChange", maxWidth: "maxWidthChange", maxHeight: "maxHeightChange", resizeStart: "resizeStart", resizeMove: "resizeMove", resizeEnd: "resizeEnd" }, host: { listeners: { "pointerdown": "onPointerDown($event)", "keydown": "onHandleKeyDown($event)" }, properties: { "
|
|
3701
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.4", type: NgxResizable, isStandalone: true, selector: "[NgxResizable],[ngxResizable]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, directions: { classPropertyName: "directions", publicName: "directions", isSignal: true, isRequired: false, transformFunction: null }, grid: { classPropertyName: "grid", publicName: "grid", isSignal: true, isRequired: false, transformFunction: null }, boundary: { classPropertyName: "boundary", publicName: "boundary", isSignal: true, isRequired: false, transformFunction: null }, keyboardStep: { classPropertyName: "keyboardStep", publicName: "keyboardStep", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", minWidth: "minWidthChange", minHeight: "minHeightChange", maxWidth: "maxWidthChange", maxHeight: "maxHeightChange", resizeStart: "resizeStart", resizeMove: "resizeMove", resizeEnd: "resizeEnd" }, host: { listeners: { "pointerdown": "onPointerDown($event)", "keydown": "onHandleKeyDown($event)" }, properties: { "attr.aria-keyshortcuts": "\"ArrowLeft ArrowRight ArrowUp ArrowDown\"" }, classAttribute: "ngx-resizable" }, ngImport: i0 });
|
|
3655
3702
|
}
|
|
3656
3703
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxResizable, decorators: [{
|
|
3657
3704
|
type: Directive,
|
|
3658
3705
|
args: [{
|
|
3659
3706
|
selector: '[NgxResizable],[ngxResizable]',
|
|
3660
3707
|
host: {
|
|
3661
|
-
'[style.touch-action]': '"none"',
|
|
3662
3708
|
class: 'ngx-resizable',
|
|
3709
|
+
// Do not set touch-action:none on the whole panel: it breaks nested controls.
|
|
3710
|
+
// '[style.touch-action]': '"none"',
|
|
3711
|
+
'[attr.aria-keyshortcuts]': '"ArrowLeft ArrowRight ArrowUp ArrowDown"',
|
|
3663
3712
|
},
|
|
3664
3713
|
}]
|
|
3665
3714
|
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }, { type: i0.Output, args: ["minWidthChange"] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }, { type: i0.Output, args: ["minHeightChange"] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }, { type: i0.Output, args: ["maxWidthChange"] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }, { type: i0.Output, args: ["maxHeightChange"] }], directions: [{ type: i0.Input, args: [{ isSignal: true, alias: "directions", required: false }] }], grid: [{ type: i0.Input, args: [{ isSignal: true, alias: "grid", required: false }] }], boundary: [{ type: i0.Input, args: [{ isSignal: true, alias: "boundary", required: false }] }], keyboardStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyboardStep", required: false }] }], resizeStart: [{ type: i0.Output, args: ["resizeStart"] }], resizeMove: [{ type: i0.Output, args: ["resizeMove"] }], resizeEnd: [{ type: i0.Output, args: ["resizeEnd"] }], onPointerDown: [{
|
|
@@ -3669,13 +3718,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
3669
3718
|
type: HostListener,
|
|
3670
3719
|
args: ['keydown', ['$event']]
|
|
3671
3720
|
}] } });
|
|
3672
|
-
function
|
|
3721
|
+
function isElementTarget(target) {
|
|
3673
3722
|
return (!!target &&
|
|
3674
3723
|
typeof target === 'object' &&
|
|
3675
3724
|
'nodeType' in target &&
|
|
3676
3725
|
target.nodeType === 1 &&
|
|
3677
3726
|
'closest' in target);
|
|
3678
3727
|
}
|
|
3728
|
+
function readBorderBoxSize(element, axis) {
|
|
3729
|
+
const win = element.ownerDocument.defaultView;
|
|
3730
|
+
const style = win?.getComputedStyle(element);
|
|
3731
|
+
if (!style)
|
|
3732
|
+
return axis === 'x' ? element.offsetWidth : element.offsetHeight;
|
|
3733
|
+
const horizontal = axis === 'x';
|
|
3734
|
+
const size = Number.parseFloat(horizontal ? style.width : style.height) || 0;
|
|
3735
|
+
if (style.boxSizing === 'border-box')
|
|
3736
|
+
return size;
|
|
3737
|
+
const px = (value) => Number.parseFloat(value) || 0;
|
|
3738
|
+
return (size +
|
|
3739
|
+
(horizontal
|
|
3740
|
+
? px(style.paddingLeft) +
|
|
3741
|
+
px(style.paddingRight) +
|
|
3742
|
+
px(style.borderLeftWidth) +
|
|
3743
|
+
px(style.borderRightWidth)
|
|
3744
|
+
: px(style.paddingTop) +
|
|
3745
|
+
px(style.paddingBottom) +
|
|
3746
|
+
px(style.borderTopWidth) +
|
|
3747
|
+
px(style.borderBottomWidth)));
|
|
3748
|
+
}
|
|
3749
|
+
/**
|
|
3750
|
+
* Compose a resize-only offset with the existing CSS individual `translate` value.
|
|
3751
|
+
* Keeping the original CSS tokens (instead of parseFloat) preserves percentages, calc(),
|
|
3752
|
+
* and variables. The `transform` channel remains exclusively owned by NgxDraggable.
|
|
3753
|
+
*/
|
|
3754
|
+
function writeTranslateWithOffset(element, baseValue, offset) {
|
|
3755
|
+
const [baseX, baseY, baseZ] = splitCssComponents(!baseValue || baseValue === 'none' ? '0px 0px 0px' : baseValue);
|
|
3756
|
+
const x = offset.x ? `calc(${baseX ?? '0px'} ${formatOffset(offset.x)})` : (baseX ?? '0px');
|
|
3757
|
+
const y = offset.y ? `calc(${baseY ?? '0px'} ${formatOffset(offset.y)})` : (baseY ?? '0px');
|
|
3758
|
+
element.style.translate = `${x} ${y} ${baseZ ?? '0px'}`;
|
|
3759
|
+
}
|
|
3760
|
+
function splitCssComponents(value) {
|
|
3761
|
+
const result = [];
|
|
3762
|
+
let depth = 0;
|
|
3763
|
+
let token = '';
|
|
3764
|
+
for (const char of value.trim()) {
|
|
3765
|
+
if (char === '(')
|
|
3766
|
+
depth++;
|
|
3767
|
+
if (char === ')')
|
|
3768
|
+
depth = Math.max(0, depth - 1);
|
|
3769
|
+
if (/\s/.test(char) && depth === 0) {
|
|
3770
|
+
if (token)
|
|
3771
|
+
result.push(token);
|
|
3772
|
+
token = '';
|
|
3773
|
+
}
|
|
3774
|
+
else {
|
|
3775
|
+
token += char;
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
if (token)
|
|
3779
|
+
result.push(token);
|
|
3780
|
+
return result;
|
|
3781
|
+
}
|
|
3782
|
+
function formatOffset(value) {
|
|
3783
|
+
return value < 0
|
|
3784
|
+
? `- ${Number(Math.abs(value).toFixed(4))}px`
|
|
3785
|
+
: `+ ${Number(value.toFixed(4))}px`;
|
|
3786
|
+
}
|
|
3679
3787
|
|
|
3680
3788
|
const NGX_PLACEHOLDER = new InjectionToken('ngx-place-holder');
|
|
3681
3789
|
/**
|
|
@@ -3819,6 +3927,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
3819
3927
|
}]
|
|
3820
3928
|
}] });
|
|
3821
3929
|
|
|
3930
|
+
/**
|
|
3931
|
+
* Typed handle API. Prefer ngxResizeHandle="se" in templates; the legacy
|
|
3932
|
+
* data-ngx-resize-handle attribute remains available for backwards compatibility.
|
|
3933
|
+
*/
|
|
3934
|
+
class NgxResizeHandle {
|
|
3935
|
+
ngxResizeHandle = input.required(/* @ts-ignore */
|
|
3936
|
+
...(ngDevMode ? [{ debugName: "ngxResizeHandle" }] : /* istanbul ignore next */ []));
|
|
3937
|
+
parent = inject(NgxResizable, { optional: true, skipSelf: true });
|
|
3938
|
+
onPointerDown(event) {
|
|
3939
|
+
this.parent?.beginResize(event, this.ngxResizeHandle());
|
|
3940
|
+
}
|
|
3941
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxResizeHandle, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3942
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.4", type: NgxResizeHandle, isStandalone: true, selector: "[ngxResizeHandle]", inputs: { ngxResizeHandle: { classPropertyName: "ngxResizeHandle", publicName: "ngxResizeHandle", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "pointerdown": "onPointerDown($event)" }, properties: { "style.touch-action": "\"none\"", "style.user-select": "\"none\"" } }, ngImport: i0 });
|
|
3943
|
+
}
|
|
3944
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxResizeHandle, decorators: [{
|
|
3945
|
+
type: Directive,
|
|
3946
|
+
args: [{
|
|
3947
|
+
selector: '[ngxResizeHandle]',
|
|
3948
|
+
standalone: true,
|
|
3949
|
+
host: {
|
|
3950
|
+
'[style.touch-action]': '"none"',
|
|
3951
|
+
'[style.user-select]': '"none"',
|
|
3952
|
+
},
|
|
3953
|
+
}]
|
|
3954
|
+
}], propDecorators: { ngxResizeHandle: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngxResizeHandle", required: true }] }], onPointerDown: [{
|
|
3955
|
+
type: HostListener,
|
|
3956
|
+
args: ['pointerdown', ['$event']]
|
|
3957
|
+
}] } });
|
|
3958
|
+
|
|
3822
3959
|
function moveItemInArray(array, from, to) {
|
|
3823
3960
|
const f = clamp(from, array.length - 1);
|
|
3824
3961
|
const t = clamp(to, array.length - 1);
|
|
@@ -3904,5 +4041,5 @@ function getCleanHtml(el, options) {
|
|
|
3904
4041
|
* Generated bundle index. Do not edit.
|
|
3905
4042
|
*/
|
|
3906
4043
|
|
|
3907
|
-
export { AutoScroller, DragDropService, DragRef, DropListGroupRef, DropListRef, NGX_DRAGGABLE, NGX_DRAG_PREVIEW, NGX_DROPLIST, NGX_DROPLIST_GROUP, NGX_PLACEHOLDER, NgxDragPreview, NgxDraggable, NgxDropList, NgxDropListGroup, NgxPlaceholder, NgxResizable, PlaceHolderRef, adjustForZoom, checkBoundX, checkBoundY, clampResizeWithinBoundary, copyArrayItem, findScrollableAncestor, findScrollableAncestorForAxis, getCleanHtml, getPageZoom, getScrollPosition, isRtl, moveItemInArray, resolveLogicalDirection, stripEditorArtifacts, transferArrayItem };
|
|
4044
|
+
export { AutoScroller, DragDropService, DragRef, DropListGroupRef, DropListRef, NGX_DRAGGABLE, NGX_DRAG_PREVIEW, NGX_DROPLIST, NGX_DROPLIST_GROUP, NGX_PLACEHOLDER, NgxDragPreview, NgxDraggable, NgxDropList, NgxDropListGroup, NgxPlaceholder, NgxResizable, NgxResizeHandle, PlaceHolderRef, adjustForZoom, checkBoundX, checkBoundY, clampResizeWithinBoundary, copyArrayItem, findScrollableAncestor, findScrollableAncestorForAxis, getCleanHtml, getPageZoom, getScrollPosition, isRtl, moveItemInArray, resolveLogicalDirection, stripEditorArtifacts, transferArrayItem };
|
|
3908
4045
|
//# sourceMappingURL=ngx-kit-drag-resize.mjs.map
|