angular-movement 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,6 +51,9 @@ function getInterpolated(arr, i1, i2, p) {
51
51
  return undefined;
52
52
  const v1 = arr[Math.min(i1, arr.length - 1)];
53
53
  const v2 = arr[Math.min(i2, arr.length - 1)];
54
+ if (typeof v1 === 'string' || typeof v2 === 'string') {
55
+ return p >= 1 ? v2 : v1;
56
+ }
54
57
  return v1 + (v2 - v1) * p;
55
58
  }
56
59
  const KNOWN_KEYS = new Set([
@@ -69,36 +72,36 @@ function buildKeyframe(frames, getVal) {
69
72
  const keyframe = {};
70
73
  const opacity = getVal(frames.opacity);
71
74
  if (opacity !== undefined) {
72
- keyframe.opacity = opacity;
75
+ keyframe.opacity = Number(opacity);
73
76
  }
74
77
  const x = getVal(frames.x);
75
78
  const y = getVal(frames.y);
76
79
  if (x !== undefined || y !== undefined) {
77
- keyframe.translate = `${x ?? 0}px ${y ?? 0}px`;
80
+ keyframe.translate = `${Number(x ?? 0)}px ${Number(y ?? 0)}px`;
78
81
  }
79
82
  const scale = getVal(frames.scale);
80
83
  if (scale !== undefined) {
81
- keyframe.scale = `${scale}`;
84
+ keyframe.scale = `${Number(scale)}`;
82
85
  }
83
86
  else {
84
87
  const scaleX = getVal(frames.scaleX);
85
88
  const scaleY = getVal(frames.scaleY);
86
89
  if (scaleX !== undefined || scaleY !== undefined) {
87
- keyframe.scale = `${scaleX ?? 1} ${scaleY ?? 1}`;
90
+ keyframe.scale = `${Number(scaleX ?? 1)} ${Number(scaleY ?? 1)}`;
88
91
  }
89
92
  }
90
93
  const rotate = getVal(frames.rotate);
91
94
  if (rotate !== undefined) {
92
- keyframe.rotate = `${rotate}deg`;
95
+ keyframe.rotate = `${Number(rotate)}deg`;
93
96
  }
94
97
  const blur = getVal(frames.blur);
95
98
  if (blur !== undefined) {
96
- keyframe.filter = `blur(${blur}px)`;
99
+ keyframe.filter = `blur(${Number(blur)}px)`;
97
100
  }
98
101
  const rotateX = getVal(frames.rotateX);
99
102
  const rotateY = getVal(frames.rotateY);
100
103
  if (rotateX !== undefined || rotateY !== undefined) {
101
- keyframe.transform = `perspective(${DEFAULT_PERSPECTIVE}) rotateX(${rotateX ?? 0}deg) rotateY(${rotateY ?? 0}deg)`;
104
+ keyframe.transform = `perspective(${DEFAULT_PERSPECTIVE}) rotateX(${Number(rotateX ?? 0)}deg) rotateY(${Number(rotateY ?? 0)}deg)`;
102
105
  }
103
106
  // Passthrough arbitrary properties for WAAPI (e.g. strokeDashoffset)
104
107
  for (const key in frames) {
@@ -310,6 +313,20 @@ const MOVE_PRESETS = {
310
313
  enter: { opacity: [0, 1], x: [-100, 0], rotate: [-120, 0] },
311
314
  leave: { opacity: [1, 0], x: [0, 100], rotate: [0, 120] },
312
315
  },
316
+ 'icon-draw': {
317
+ enter: { pathLength: [0, 1], opacity: [0, 1] },
318
+ leave: { pathLength: [1, 0], opacity: [1, 0] },
319
+ },
320
+ 'icon-pulse': {
321
+ enter: { scale: [1, 1.08, 1], opacity: [1, 0.85, 1] },
322
+ leave: { scale: [1, 0.92, 1], opacity: [1, 1, 1] },
323
+ loop: { scale: [1, 1.08, 1], opacity: [1, 0.85, 1] },
324
+ },
325
+ 'icon-bounce': {
326
+ enter: { y: [0, -3, 0], opacity: [1, 1, 1] },
327
+ leave: { y: [0, 0, 0], opacity: [1, 1, 1] },
328
+ loop: { y: [0, -3, 0] },
329
+ },
313
330
  none: {
314
331
  enter: { opacity: [1, 1] },
315
332
  leave: { opacity: [1, 1] },
@@ -449,7 +466,9 @@ class WaapiPlayer {
449
466
  onDone?.();
450
467
  return;
451
468
  }
452
- const keyframes = this.#toWAAPIKeyframes(frames);
469
+ const keyframes = Array.isArray(frames)
470
+ ? frames
471
+ : this.#toWAAPIKeyframes(frames);
453
472
  const iterations = config.iterations ?? 1;
454
473
  this.#animation = host.animate(keyframes, {
455
474
  duration: config.duration,
@@ -638,25 +657,127 @@ class SpringPlayer {
638
657
  }
639
658
  }
640
659
 
660
+ function isPropertyTransition(value) {
661
+ return (typeof value === 'object' &&
662
+ value !== null &&
663
+ ('duration' in value || 'easing' in value || 'delay' in value));
664
+ }
665
+ function composeTransitionKeyframes(frames, transition, baseConfig) {
666
+ const globalDuration = transition.duration ?? baseConfig.duration;
667
+ const globalEasing = transition.easing ?? baseConfig.easing;
668
+ const globalDelay = transition.delay ?? baseConfig.delay;
669
+ const propNames = Object.keys(frames).filter((k) => k !== 'transition');
670
+ if (propNames.length === 0)
671
+ return null;
672
+ const timings = propNames.map((prop) => {
673
+ const pt = transition[prop];
674
+ const parsed = isPropertyTransition(pt) ? pt : {};
675
+ return {
676
+ prop,
677
+ duration: parsed.duration ?? globalDuration,
678
+ easing: parsed.easing ?? globalEasing,
679
+ delay: parsed.delay ?? globalDelay,
680
+ values: frames[prop].map((v) => Number(v)),
681
+ };
682
+ });
683
+ const allSame = timings.every((t) => t.duration === timings[0].duration &&
684
+ t.easing === timings[0].easing &&
685
+ t.delay === timings[0].delay);
686
+ if (allSame) {
687
+ return null;
688
+ }
689
+ const uniqueEasings = new Set(timings.map((t) => t.easing));
690
+ let finalEasing = timings[0].easing;
691
+ if (uniqueEasings.size > 1) {
692
+ if (typeof ngDevMode !== 'undefined' && ngDevMode) {
693
+ console.warn('[Movement] Per-property easing differences are not supported yet. Using global easing.');
694
+ }
695
+ finalEasing = globalEasing;
696
+ }
697
+ const totalDuration = Math.max(...timings.map((t) => t.delay + t.duration));
698
+ const totalDelay = Math.min(...timings.map((t) => t.delay));
699
+ // Collect all keyframe times
700
+ const timeSet = new Set();
701
+ for (const t of timings) {
702
+ const n = t.values.length;
703
+ for (let i = 0; i < n; i++) {
704
+ const time = t.delay + (t.duration * i) / Math.max(1, n - 1);
705
+ timeSet.add(time);
706
+ }
707
+ }
708
+ const sortedTimes = Array.from(timeSet).sort((a, b) => a - b);
709
+ const resultKeyframes = [];
710
+ for (const time of sortedTimes) {
711
+ const offset = totalDuration > totalDelay ? (time - totalDelay) / (totalDuration - totalDelay) : 0;
712
+ const kf = { offset };
713
+ for (const t of timings) {
714
+ const localTime = time - t.delay;
715
+ const n = t.values.length;
716
+ if (n === 1) {
717
+ kf[t.prop] = t.values[0];
718
+ continue;
719
+ }
720
+ if (localTime <= 0) {
721
+ kf[t.prop] = t.values[0];
722
+ }
723
+ else if (localTime >= t.duration) {
724
+ kf[t.prop] = t.values[n - 1];
725
+ }
726
+ else {
727
+ const progress = t.duration > 0 ? localTime / t.duration : 0;
728
+ const maxIdx = n - 1;
729
+ const idx = progress * maxIdx;
730
+ const i1 = Math.floor(idx);
731
+ const i2 = Math.min(Math.ceil(idx), maxIdx);
732
+ const p = idx - i1;
733
+ const v1 = t.values[i1];
734
+ const v2 = t.values[i2];
735
+ kf[t.prop] = v1 + (v2 - v1) * p;
736
+ }
737
+ }
738
+ resultKeyframes.push(kf);
739
+ }
740
+ return {
741
+ keyframes: resultKeyframes,
742
+ duration: totalDuration,
743
+ easing: finalEasing,
744
+ delay: totalDelay,
745
+ };
746
+ }
747
+
641
748
  class AnimationEngine {
642
749
  #platformId = inject(PLATFORM_ID);
643
750
  #defaults = inject(MOVEMENT_CONFIG);
644
- play(host, frames, options = {}) {
751
+ play(host, rawFrames, options = {}) {
645
752
  if (!isPlatformBrowser(this.#platformId)) {
646
753
  options.onDone?.();
647
754
  return null;
648
755
  }
756
+ const frames = this.#resolveSvgFrames(host, rawFrames);
649
757
  if (options.disabled) {
650
- this.#prepareSvgStrokeDraw(host, frames);
758
+ this.#prepareSvgPathDraw(host, frames);
651
759
  this.#applyFinalStyles(host, frames);
652
760
  options.onDone?.();
653
761
  return null;
654
762
  }
655
- this.#prepareSvgStrokeDraw(host, frames);
763
+ this.#prepareSvgPathDraw(host, frames);
656
764
  const config = options.config ?? this.#defaults;
657
765
  const spring = validateSpring(options.spring);
658
766
  const isSpring = spring || config.easing === 'spring';
659
767
  const iterations = options.iterations ?? config.iterations;
768
+ // Per-property transitions only supported with WaapiPlayer (not spring)
769
+ if (options.transition && !isSpring) {
770
+ const resolved = composeTransitionKeyframes(frames, options.transition, config);
771
+ if (resolved) {
772
+ return new WaapiPlayer(host, resolved.keyframes, {
773
+ duration: resolved.duration,
774
+ easing: resolved.easing,
775
+ delay: resolved.delay,
776
+ disabled: false,
777
+ iterations,
778
+ }, options.onDone);
779
+ }
780
+ }
660
781
  if (isSpring) {
661
782
  return new SpringPlayer(host, frames, spring ?? {}, options.delay ?? config.delay, iterations, options.onDone);
662
783
  }
@@ -673,20 +794,58 @@ class AnimationEngine {
673
794
  #applyFinalStyles(host, frames) {
674
795
  applyComposedStyle(host, composeFinalStyle(frames));
675
796
  }
676
- #prepareSvgStrokeDraw(host, frames) {
677
- if (!frames['strokeDashoffset'] || !this.#isSvgGeometryElement(host)) {
797
+ #resolveSvgFrames(host, frames) {
798
+ if (!frames.pathLength && !frames.pathOffset) {
799
+ return frames;
800
+ }
801
+ const L = this.#getPathLength(host);
802
+ const resolved = { ...frames };
803
+ const pValues = frames.pathLength ? frames.pathLength.map((v) => Number(v)) : [1];
804
+ const oValues = frames.pathOffset ? frames.pathOffset.map((v) => Number(v)) : [0];
805
+ const maxLen = Math.max(pValues.length, oValues.length);
806
+ const strokeDasharray = [];
807
+ const strokeDashoffset = [];
808
+ for (let i = 0; i < maxLen; i++) {
809
+ const p = pValues[Math.min(i, pValues.length - 1)];
810
+ const o = oValues[Math.min(i, oValues.length - 1)];
811
+ strokeDasharray.push(`${p * L} ${L}`);
812
+ strokeDashoffset.push(-o * L);
813
+ }
814
+ resolved['strokeDasharray'] = strokeDasharray;
815
+ resolved['strokeDashoffset'] = strokeDashoffset;
816
+ delete resolved['pathLength'];
817
+ delete resolved['pathOffset'];
818
+ return resolved;
819
+ }
820
+ #prepareSvgPathDraw(host, frames) {
821
+ const hasPathProps = frames.strokeDashoffset || frames.strokeDasharray || frames.pathLength || frames.pathOffset;
822
+ if (!hasPathProps || !this.#isSvgGeometryElement(host)) {
678
823
  return;
679
824
  }
680
- let length = 28;
825
+ const styledHost = host;
826
+ const L = this.#getPathLength(host);
827
+ if (frames.strokeDasharray && frames.strokeDasharray.length > 0) {
828
+ styledHost.style.strokeDasharray = String(frames.strokeDasharray[0]);
829
+ }
830
+ else if (frames.strokeDashoffset || frames.pathLength || frames.pathOffset) {
831
+ styledHost.style.strokeDasharray = `${L}`;
832
+ }
833
+ if (frames.strokeDashoffset && frames.strokeDashoffset.length > 0) {
834
+ styledHost.style.strokeDashoffset = String(frames.strokeDashoffset[0]);
835
+ }
836
+ else if (frames.pathLength && frames.pathLength.length > 0) {
837
+ styledHost.style.strokeDashoffset = `${Number(frames.pathLength[0]) * L}`;
838
+ }
839
+ }
840
+ #getPathLength(host) {
841
+ if (!this.#isSvgGeometryElement(host))
842
+ return 28;
681
843
  try {
682
- length = host.getTotalLength() || length;
844
+ return host.getTotalLength() || 28;
683
845
  }
684
846
  catch {
685
- length = 28;
847
+ return 28;
686
848
  }
687
- const styledHost = host;
688
- styledHost.style.strokeDasharray = `${length}`;
689
- styledHost.style.strokeDashoffset = `${length}`;
690
849
  }
691
850
  #isSvgGeometryElement(host) {
692
851
  const view = host.ownerDocument?.defaultView;
@@ -742,7 +901,7 @@ class MoveVariantsDirective {
742
901
  if (!state)
743
902
  return;
744
903
  this.#currentPlayer?.cancel();
745
- const { spring, duration, easing, delay, ...keyframesMap } = state;
904
+ const { spring, duration, easing, delay, transition, ...keyframesMap } = state;
746
905
  const keyframes = keyframesMap;
747
906
  const staggerDelay = this.#stagger?.getDelay(this.#host.nativeElement) ?? 0;
748
907
  const config = resolveMovementConfig(this.#defaults, {
@@ -755,6 +914,7 @@ class MoveVariantsDirective {
755
914
  config,
756
915
  spring: spring ?? this.moveSpring(),
757
916
  disabled: config.disabled,
917
+ transition,
758
918
  });
759
919
  });
760
920
  }
@@ -930,7 +1090,7 @@ function statesToKeyframes(from, to) {
930
1090
  for (const key of Object.keys(from)) {
931
1091
  const f = from[key];
932
1092
  const t = to[key];
933
- if (f !== undefined && t !== undefined) {
1093
+ if (typeof f === 'number' && typeof t === 'number') {
934
1094
  result[key] = [f, t];
935
1095
  }
936
1096
  }
@@ -1029,13 +1189,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
1029
1189
  }]
1030
1190
  }], propDecorators: { moveLeave: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveLeave", required: false }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }] } });
1031
1191
 
1192
+ function optionalNumberAttribute$3(value) {
1193
+ if (value === undefined || value === null || value === '') {
1194
+ return undefined;
1195
+ }
1196
+ return Number(value);
1197
+ }
1032
1198
  class MoveHoverDirective {
1033
1199
  moveWhileHover = input.required(...(ngDevMode ? [{ debugName: "moveWhileHover" }] : /* istanbul ignore next */ []));
1034
- moveDuration = input(undefined, ...(ngDevMode ? [{ debugName: "moveDuration" }] : /* istanbul ignore next */ []));
1200
+ moveDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$3 });
1035
1201
  moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
1036
- moveDelay = input(undefined, ...(ngDevMode ? [{ debugName: "moveDelay" }] : /* istanbul ignore next */ []));
1202
+ moveDelay = input(undefined, { ...(ngDevMode ? { debugName: "moveDelay" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$3 });
1037
1203
  moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
1038
1204
  moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
1205
+ moveReverseDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveReverseDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$3 });
1206
+ moveReverseEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveReverseEasing" }] : /* istanbul ignore next */ []));
1039
1207
  #defaults = inject(MOVEMENT_CONFIG);
1040
1208
  #documentRef = inject(DOCUMENT);
1041
1209
  #host = inject((ElementRef));
@@ -1080,10 +1248,22 @@ class MoveHoverDirective {
1080
1248
  return;
1081
1249
  let frames = resolveMoveFrames(this.moveWhileHover(), 'enter');
1082
1250
  if (reverse) {
1251
+ const reverseDuration = this.moveReverseDuration();
1252
+ if (reverseDuration === 0) {
1253
+ clearComposedStyle(this.#host.nativeElement, Object.keys(frames));
1254
+ return;
1255
+ }
1083
1256
  frames = reverseFrames(frames);
1084
1257
  }
1258
+ const reverseConfig = reverse
1259
+ ? resolveMovementConfig({ ...this.#defaults, duration: 200, easing: 'ease-out', delay: 0 }, {
1260
+ duration: this.moveReverseDuration() ?? this.moveDuration(),
1261
+ easing: this.moveReverseEasing(),
1262
+ delay: 0,
1263
+ }, isReduced)
1264
+ : config;
1085
1265
  this.#currentPlayer = this.#engine.play(this.#host.nativeElement, frames, {
1086
- config,
1266
+ config: reverseConfig,
1087
1267
  spring: this.moveSpring(),
1088
1268
  disabled: false,
1089
1269
  });
@@ -1092,7 +1272,7 @@ class MoveHoverDirective {
1092
1272
  this.#currentPlayer?.cancel();
1093
1273
  }
1094
1274
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveHoverDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1095
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveHoverDirective, isStandalone: true, selector: "[moveWhileHover]", inputs: { moveWhileHover: { classPropertyName: "moveWhileHover", publicName: "moveWhileHover", isSignal: true, isRequired: true, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "touchstart": "onTouchStart($event)", "touchend": "onTouchEnd()", "touchcancel": "onTouchEnd()" } }, ngImport: i0 });
1275
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveHoverDirective, isStandalone: true, selector: "[moveWhileHover]", inputs: { moveWhileHover: { classPropertyName: "moveWhileHover", publicName: "moveWhileHover", isSignal: true, isRequired: true, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null }, moveReverseDuration: { classPropertyName: "moveReverseDuration", publicName: "moveReverseDuration", isSignal: true, isRequired: false, transformFunction: null }, moveReverseEasing: { classPropertyName: "moveReverseEasing", publicName: "moveReverseEasing", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "touchstart": "onTouchStart($event)", "touchend": "onTouchEnd()", "touchcancel": "onTouchEnd()" } }, ngImport: i0 });
1096
1276
  }
1097
1277
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveHoverDirective, decorators: [{
1098
1278
  type: Directive,
@@ -1106,15 +1286,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
1106
1286
  '(touchcancel)': 'onTouchEnd()',
1107
1287
  },
1108
1288
  }]
1109
- }], propDecorators: { moveWhileHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveWhileHover", required: true }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }] } });
1289
+ }], propDecorators: { moveWhileHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveWhileHover", required: true }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }], moveReverseDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseDuration", required: false }] }], moveReverseEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseEasing", required: false }] }] } });
1110
1290
 
1291
+ function optionalNumberAttribute$2(value) {
1292
+ if (value === undefined || value === null || value === '') {
1293
+ return undefined;
1294
+ }
1295
+ return Number(value);
1296
+ }
1111
1297
  class MoveTapDirective {
1112
1298
  moveWhileTap = input.required(...(ngDevMode ? [{ debugName: "moveWhileTap" }] : /* istanbul ignore next */ []));
1113
- moveDuration = input(undefined, ...(ngDevMode ? [{ debugName: "moveDuration" }] : /* istanbul ignore next */ []));
1299
+ moveDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$2 });
1114
1300
  moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
1115
- moveDelay = input(undefined, ...(ngDevMode ? [{ debugName: "moveDelay" }] : /* istanbul ignore next */ []));
1301
+ moveDelay = input(undefined, { ...(ngDevMode ? { debugName: "moveDelay" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$2 });
1116
1302
  moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
1117
1303
  moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
1304
+ moveReverseDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveReverseDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$2 });
1305
+ moveReverseEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveReverseEasing" }] : /* istanbul ignore next */ []));
1118
1306
  #defaults = inject(MOVEMENT_CONFIG);
1119
1307
  #documentRef = inject(DOCUMENT);
1120
1308
  #host = inject((ElementRef));
@@ -1146,10 +1334,22 @@ class MoveTapDirective {
1146
1334
  return;
1147
1335
  let frames = resolveMoveFrames(this.moveWhileTap(), 'enter');
1148
1336
  if (reverse) {
1337
+ const reverseDuration = this.moveReverseDuration();
1338
+ if (reverseDuration === 0) {
1339
+ clearComposedStyle(this.#host.nativeElement, Object.keys(frames));
1340
+ return;
1341
+ }
1149
1342
  frames = reverseFrames(frames);
1150
1343
  }
1344
+ const reverseConfig = reverse
1345
+ ? resolveMovementConfig({ ...this.#defaults, duration: 200, easing: 'ease-out', delay: 0 }, {
1346
+ duration: this.moveReverseDuration() ?? this.moveDuration(),
1347
+ easing: this.moveReverseEasing(),
1348
+ delay: 0,
1349
+ }, isReduced)
1350
+ : config;
1151
1351
  this.#currentPlayer = this.#engine.play(this.#host.nativeElement, frames, {
1152
- config,
1352
+ config: reverseConfig,
1153
1353
  spring: this.moveSpring(),
1154
1354
  disabled: false,
1155
1355
  });
@@ -1158,7 +1358,7 @@ class MoveTapDirective {
1158
1358
  this.#currentPlayer?.cancel();
1159
1359
  }
1160
1360
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTapDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1161
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveTapDirective, isStandalone: true, selector: "[moveWhileTap]", inputs: { moveWhileTap: { classPropertyName: "moveWhileTap", publicName: "moveWhileTap", isSignal: true, isRequired: true, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointerdown": "onPointerDown()", "pointerup": "onPointerUp()", "pointercancel": "onPointerUp()", "pointerleave": "onPointerUp()" } }, ngImport: i0 });
1361
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveTapDirective, isStandalone: true, selector: "[moveWhileTap]", inputs: { moveWhileTap: { classPropertyName: "moveWhileTap", publicName: "moveWhileTap", isSignal: true, isRequired: true, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null }, moveReverseDuration: { classPropertyName: "moveReverseDuration", publicName: "moveReverseDuration", isSignal: true, isRequired: false, transformFunction: null }, moveReverseEasing: { classPropertyName: "moveReverseEasing", publicName: "moveReverseEasing", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointerdown": "onPointerDown()", "pointerup": "onPointerUp()", "pointercancel": "onPointerUp()", "pointerleave": "onPointerUp()" } }, ngImport: i0 });
1162
1362
  }
1163
1363
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTapDirective, decorators: [{
1164
1364
  type: Directive,
@@ -1171,7 +1371,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
1171
1371
  '(pointerleave)': 'onPointerUp()',
1172
1372
  },
1173
1373
  }]
1174
- }], propDecorators: { moveWhileTap: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveWhileTap", required: true }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }] } });
1374
+ }], propDecorators: { moveWhileTap: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveWhileTap", required: true }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }], moveReverseDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseDuration", required: false }] }], moveReverseEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseEasing", required: false }] }] } });
1175
1375
 
1176
1376
  class MoveStaggerDirective {
1177
1377
  moveStagger = input.required(...(ngDevMode ? [{ debugName: "moveStagger" }] : /* istanbul ignore next */ []));
@@ -2455,7 +2655,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
2455
2655
  }]
2456
2656
  }], propDecorators: { moveLoop: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveLoop", required: false }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }] } });
2457
2657
 
2458
- function optionalNumberAttribute(value) {
2658
+ function optionalNumberAttribute$1(value) {
2459
2659
  if (value === undefined || value === null || value === '') {
2460
2660
  return undefined;
2461
2661
  }
@@ -2464,13 +2664,14 @@ function optionalNumberAttribute(value) {
2464
2664
  class MoveTargetDirective {
2465
2665
  moveTarget = input.required(...(ngDevMode ? [{ debugName: "moveTarget" }] : /* istanbul ignore next */ []));
2466
2666
  moveFrames = input.required(...(ngDevMode ? [{ debugName: "moveFrames" }] : /* istanbul ignore next */ []));
2467
- moveDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
2667
+ moveDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$1 });
2468
2668
  moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
2469
- moveDelay = input(undefined, { ...(ngDevMode ? { debugName: "moveDelay" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
2669
+ moveDelay = input(undefined, { ...(ngDevMode ? { debugName: "moveDelay" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$1 });
2470
2670
  moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
2471
2671
  moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
2472
- moveReverseDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveReverseDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
2672
+ moveReverseDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveReverseDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$1 });
2473
2673
  moveReverseEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveReverseEasing" }] : /* istanbul ignore next */ []));
2674
+ moveTransition = input(undefined, ...(ngDevMode ? [{ debugName: "moveTransition" }] : /* istanbul ignore next */ []));
2474
2675
  #defaults = inject(MOVEMENT_CONFIG);
2475
2676
  #documentRef = inject(DOCUMENT);
2476
2677
  #host = inject((ElementRef));
@@ -2502,6 +2703,7 @@ class MoveTargetDirective {
2502
2703
  config,
2503
2704
  spring: this.moveSpring(),
2504
2705
  disabled: config.disabled,
2706
+ transition: this.moveTransition(),
2505
2707
  });
2506
2708
  }
2507
2709
  #playReverse(frames) {
@@ -2517,6 +2719,7 @@ class MoveTargetDirective {
2517
2719
  config,
2518
2720
  spring: this.moveSpring(),
2519
2721
  disabled: config.disabled,
2722
+ transition: this.moveTransition(),
2520
2723
  });
2521
2724
  }
2522
2725
  ngOnDestroy() {
@@ -2524,7 +2727,7 @@ class MoveTargetDirective {
2524
2727
  this.#currentPlayer?.cancel();
2525
2728
  }
2526
2729
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTargetDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2527
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveTargetDirective, isStandalone: true, selector: "[moveTarget]", inputs: { moveTarget: { classPropertyName: "moveTarget", publicName: "moveTarget", isSignal: true, isRequired: true, transformFunction: null }, moveFrames: { classPropertyName: "moveFrames", publicName: "moveFrames", isSignal: true, isRequired: true, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveReverseDuration: { classPropertyName: "moveReverseDuration", publicName: "moveReverseDuration", isSignal: true, isRequired: false, transformFunction: null }, moveReverseEasing: { classPropertyName: "moveReverseEasing", publicName: "moveReverseEasing", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
2730
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveTargetDirective, isStandalone: true, selector: "[moveTarget]", inputs: { moveTarget: { classPropertyName: "moveTarget", publicName: "moveTarget", isSignal: true, isRequired: true, transformFunction: null }, moveFrames: { classPropertyName: "moveFrames", publicName: "moveFrames", isSignal: true, isRequired: true, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveReverseDuration: { classPropertyName: "moveReverseDuration", publicName: "moveReverseDuration", isSignal: true, isRequired: false, transformFunction: null }, moveReverseEasing: { classPropertyName: "moveReverseEasing", publicName: "moveReverseEasing", isSignal: true, isRequired: false, transformFunction: null }, moveTransition: { classPropertyName: "moveTransition", publicName: "moveTransition", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
2528
2731
  }
2529
2732
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTargetDirective, decorators: [{
2530
2733
  type: Directive,
@@ -2532,7 +2735,202 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
2532
2735
  selector: '[moveTarget]',
2533
2736
  standalone: true,
2534
2737
  }]
2535
- }], propDecorators: { moveTarget: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveTarget", required: true }] }], moveFrames: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveFrames", required: true }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveReverseDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseDuration", required: false }] }], moveReverseEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseEasing", required: false }] }] } });
2738
+ }], propDecorators: { moveTarget: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveTarget", required: true }] }], moveFrames: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveFrames", required: true }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveReverseDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseDuration", required: false }] }], moveReverseEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseEasing", required: false }] }], moveTransition: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveTransition", required: false }] }] } });
2739
+
2740
+ function optionalNumberAttribute(value) {
2741
+ if (value === undefined || value === null || value === '') {
2742
+ return undefined;
2743
+ }
2744
+ return Number(value);
2745
+ }
2746
+ class MoveTriggerDirective {
2747
+ moveTrigger = input.required(...(ngDevMode ? [{ debugName: "moveTrigger" }] : /* istanbul ignore next */ []));
2748
+ moveFrames = input.required(...(ngDevMode ? [{ debugName: "moveFrames" }] : /* istanbul ignore next */ []));
2749
+ moveResetFrames = input(undefined, ...(ngDevMode ? [{ debugName: "moveResetFrames" }] : /* istanbul ignore next */ []));
2750
+ moveResetState = input('clear', ...(ngDevMode ? [{ debugName: "moveResetState" }] : /* istanbul ignore next */ []));
2751
+ moveDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
2752
+ moveEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveEasing" }] : /* istanbul ignore next */ []));
2753
+ moveDelay = input(undefined, { ...(ngDevMode ? { debugName: "moveDelay" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
2754
+ moveSpring = input(undefined, ...(ngDevMode ? [{ debugName: "moveSpring" }] : /* istanbul ignore next */ []));
2755
+ moveDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "moveDisabled" }] : /* istanbul ignore next */ []));
2756
+ moveReverseDuration = input(undefined, { ...(ngDevMode ? { debugName: "moveReverseDuration" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute });
2757
+ moveReverseEasing = input(undefined, ...(ngDevMode ? [{ debugName: "moveReverseEasing" }] : /* istanbul ignore next */ []));
2758
+ #defaults = inject(MOVEMENT_CONFIG);
2759
+ #documentRef = inject(DOCUMENT);
2760
+ #host = inject((ElementRef));
2761
+ #engine = inject(AnimationEngine);
2762
+ #currentPlayer = null;
2763
+ #hasPlayedForward = false;
2764
+ #triggerEffect = effect(() => {
2765
+ const active = this.moveTrigger();
2766
+ const frames = this.moveFrames();
2767
+ if (active) {
2768
+ this.#playForward(frames);
2769
+ this.#hasPlayedForward = true;
2770
+ return;
2771
+ }
2772
+ if (this.#hasPlayedForward) {
2773
+ this.#playReset(frames);
2774
+ }
2775
+ }, ...(ngDevMode ? [{ debugName: "#triggerEffect" }] : /* istanbul ignore next */ []));
2776
+ play(frames) {
2777
+ const targetFrames = frames ?? this.moveFrames();
2778
+ this.#playForward(targetFrames);
2779
+ this.#hasPlayedForward = true;
2780
+ return this.#currentPlayer?.finished ?? Promise.resolve();
2781
+ }
2782
+ reset() {
2783
+ this.#currentPlayer?.cancel();
2784
+ const frames = this.moveFrames();
2785
+ this.#applyReset(frames);
2786
+ }
2787
+ set(state) {
2788
+ this.#currentPlayer?.cancel();
2789
+ applyComposedStyle(this.#host.nativeElement, state);
2790
+ }
2791
+ #playForward(frames) {
2792
+ this.#currentPlayer?.cancel();
2793
+ const isReduced = prefersReducedMotion(this.#documentRef);
2794
+ const config = resolveMovementConfig(this.#defaults, {
2795
+ duration: this.moveDuration(),
2796
+ easing: this.moveEasing(),
2797
+ delay: this.moveDelay(),
2798
+ disabled: this.moveDisabled(),
2799
+ }, isReduced);
2800
+ this.#currentPlayer = this.#engine.play(this.#host.nativeElement, frames, {
2801
+ config,
2802
+ spring: this.moveSpring(),
2803
+ disabled: config.disabled,
2804
+ });
2805
+ }
2806
+ #playReset(frames) {
2807
+ this.#currentPlayer?.cancel();
2808
+ const resetFrames = this.moveResetFrames();
2809
+ if (resetFrames) {
2810
+ const isReduced = prefersReducedMotion(this.#documentRef);
2811
+ const config = resolveMovementConfig({ ...this.#defaults, duration: 200, easing: 'ease-out', delay: 0 }, {
2812
+ duration: this.moveReverseDuration() ?? this.moveDuration(),
2813
+ easing: this.moveReverseEasing(),
2814
+ delay: 0,
2815
+ disabled: this.moveDisabled(),
2816
+ }, isReduced);
2817
+ this.#currentPlayer = this.#engine.play(this.#host.nativeElement, resetFrames, {
2818
+ config,
2819
+ spring: this.moveSpring(),
2820
+ disabled: config.disabled,
2821
+ });
2822
+ return;
2823
+ }
2824
+ const reverseDuration = this.moveReverseDuration();
2825
+ if (reverseDuration === 0) {
2826
+ this.#applyReset(frames);
2827
+ return;
2828
+ }
2829
+ const isReduced = prefersReducedMotion(this.#documentRef);
2830
+ const config = resolveMovementConfig({ ...this.#defaults, duration: 200, easing: 'ease-out', delay: 0 }, {
2831
+ duration: reverseDuration ?? this.moveDuration(),
2832
+ easing: this.moveReverseEasing(),
2833
+ delay: 0,
2834
+ disabled: this.moveDisabled(),
2835
+ }, isReduced);
2836
+ if (config.disabled) {
2837
+ this.#applyReset(frames);
2838
+ return;
2839
+ }
2840
+ // For triggers, reverse is typically not desired; we reset to initial/clear.
2841
+ // We apply the initial style of the forward frames to restore state.
2842
+ this.#applyReset(frames);
2843
+ }
2844
+ #applyReset(frames) {
2845
+ const mode = this.moveResetState();
2846
+ const host = this.#host.nativeElement;
2847
+ if (mode === 'clear') {
2848
+ clearComposedStyle(host, Object.keys(frames));
2849
+ return;
2850
+ }
2851
+ if (mode === 'initial') {
2852
+ clearComposedStyle(host, Object.keys(frames));
2853
+ applyComposedStyle(host, composeInitialStyle(frames));
2854
+ return;
2855
+ }
2856
+ if (mode === 'final') {
2857
+ clearComposedStyle(host, Object.keys(frames));
2858
+ applyComposedStyle(host, composeFinalStyle(frames));
2859
+ }
2860
+ }
2861
+ ngOnDestroy() {
2862
+ this.#triggerEffect.destroy();
2863
+ this.#currentPlayer?.cancel();
2864
+ const frames = this.moveFrames();
2865
+ if (frames) {
2866
+ clearComposedStyle(this.#host.nativeElement, Object.keys(frames));
2867
+ }
2868
+ }
2869
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2870
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.2", type: MoveTriggerDirective, isStandalone: true, selector: "[moveTrigger]", inputs: { moveTrigger: { classPropertyName: "moveTrigger", publicName: "moveTrigger", isSignal: true, isRequired: true, transformFunction: null }, moveFrames: { classPropertyName: "moveFrames", publicName: "moveFrames", isSignal: true, isRequired: true, transformFunction: null }, moveResetFrames: { classPropertyName: "moveResetFrames", publicName: "moveResetFrames", isSignal: true, isRequired: false, transformFunction: null }, moveResetState: { classPropertyName: "moveResetState", publicName: "moveResetState", isSignal: true, isRequired: false, transformFunction: null }, moveDuration: { classPropertyName: "moveDuration", publicName: "moveDuration", isSignal: true, isRequired: false, transformFunction: null }, moveEasing: { classPropertyName: "moveEasing", publicName: "moveEasing", isSignal: true, isRequired: false, transformFunction: null }, moveDelay: { classPropertyName: "moveDelay", publicName: "moveDelay", isSignal: true, isRequired: false, transformFunction: null }, moveSpring: { classPropertyName: "moveSpring", publicName: "moveSpring", isSignal: true, isRequired: false, transformFunction: null }, moveDisabled: { classPropertyName: "moveDisabled", publicName: "moveDisabled", isSignal: true, isRequired: false, transformFunction: null }, moveReverseDuration: { classPropertyName: "moveReverseDuration", publicName: "moveReverseDuration", isSignal: true, isRequired: false, transformFunction: null }, moveReverseEasing: { classPropertyName: "moveReverseEasing", publicName: "moveReverseEasing", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["moveTrigger"], ngImport: i0 });
2871
+ }
2872
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: MoveTriggerDirective, decorators: [{
2873
+ type: Directive,
2874
+ args: [{
2875
+ selector: '[moveTrigger]',
2876
+ standalone: true,
2877
+ exportAs: 'moveTrigger',
2878
+ }]
2879
+ }], propDecorators: { moveTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveTrigger", required: true }] }], moveFrames: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveFrames", required: true }] }], moveResetFrames: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveResetFrames", required: false }] }], moveResetState: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveResetState", required: false }] }], moveDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDuration", required: false }] }], moveEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveEasing", required: false }] }], moveDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDelay", required: false }] }], moveSpring: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveSpring", required: false }] }], moveDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveDisabled", required: false }] }], moveReverseDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseDuration", required: false }] }], moveReverseEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "moveReverseEasing", required: false }] }] } });
2880
+
2881
+ /**
2882
+ * Returns keyframes for a path-drawing animation.
2883
+ * Ideal for SVG `<path>`, `<circle>`, `<line>`, etc.
2884
+ *
2885
+ * @example
2886
+ * ```html
2887
+ * <path [moveTarget]="animate()" [moveFrames]="movePathDraw({ opacity: [0, 1] })" moveDuration="700" />
2888
+ * ```
2889
+ */
2890
+ function movePathDraw(overrides) {
2891
+ return {
2892
+ pathLength: [0, 1],
2893
+ opacity: [0, 1],
2894
+ ...overrides,
2895
+ };
2896
+ }
2897
+ /**
2898
+ * Returns keyframes for a subtle pulse animation on an icon.
2899
+ */
2900
+ function moveIconPulse(overrides) {
2901
+ return {
2902
+ scale: [1, 1.08, 1],
2903
+ opacity: [1, 0.85, 1],
2904
+ ...overrides,
2905
+ };
2906
+ }
2907
+ /**
2908
+ * Returns keyframes for a subtle bounce animation on an icon.
2909
+ */
2910
+ function moveIconBounce(overrides) {
2911
+ return {
2912
+ y: [0, -3, 0],
2913
+ ...overrides,
2914
+ };
2915
+ }
2916
+ /**
2917
+ * Returns keyframes for a subtle shake animation on an icon.
2918
+ */
2919
+ function moveIconShake(overrides) {
2920
+ return {
2921
+ rotate: [0, -8, 8, -8, 8, 0],
2922
+ ...overrides,
2923
+ };
2924
+ }
2925
+ /**
2926
+ * Returns keyframes for a subtle rotate animation on an icon.
2927
+ */
2928
+ function moveIconRotate(overrides) {
2929
+ return {
2930
+ rotate: [0, 15, 0],
2931
+ ...overrides,
2932
+ };
2933
+ }
2536
2934
 
2537
2935
  function provideMovement(config = {}) {
2538
2936
  return makeEnvironmentProviders([
@@ -2566,6 +2964,7 @@ const MOVEMENT_DIRECTIVES = [
2566
2964
  MoveAnimationDirective,
2567
2965
  MoveLoopDirective,
2568
2966
  MoveTargetDirective,
2967
+ MoveTriggerDirective,
2569
2968
  ];
2570
2969
 
2571
2970
  /*
@@ -2576,5 +2975,5 @@ const MOVEMENT_DIRECTIVES = [
2576
2975
  * Generated bundle index. Do not edit.
2577
2976
  */
2578
2977
 
2579
- export { AnimationEngine, MOVEMENT_CONFIG, MOVEMENT_DEFAULTS, MOVEMENT_DIRECTIVES, MOVE_PRESENCE_PARENT, MOVE_PRESETS, MOVE_STAGGER_PARENT, MOVE_VARIANTS_PARENT, MoveAnimateDirective, MoveAnimationDirective, MoveDragDirective, MoveEnterDirective, MoveFocusDirective, MoveHoverDirective, MoveInViewDirective, MoveLayoutDirective, MoveLeaveDirective, MoveLoopDirective, MoveParallaxDirective, MovePresenceDirective, MoveScrollDirective, MoveSmoothScrollDirective, MoveStaggerDirective, MoveTapDirective, MoveTargetDirective, MoveTextDirective, MoveVariantsDirective, SmoothScrollService, SpringPlayer, WaapiPlayer, applyInitialStyles, clearInitialStyles, isValidScrollOffset, prefersReducedMotion, provideMovement, resolveMoveFrames, resolveMovementConfig, reverseFrames, validateDragElastic, validateSpring };
2978
+ export { AnimationEngine, MOVEMENT_CONFIG, MOVEMENT_DEFAULTS, MOVEMENT_DIRECTIVES, MOVE_PRESENCE_PARENT, MOVE_PRESETS, MOVE_STAGGER_PARENT, MOVE_VARIANTS_PARENT, MoveAnimateDirective, MoveAnimationDirective, MoveDragDirective, MoveEnterDirective, MoveFocusDirective, MoveHoverDirective, MoveInViewDirective, MoveLayoutDirective, MoveLeaveDirective, MoveLoopDirective, MoveParallaxDirective, MovePresenceDirective, MoveScrollDirective, MoveSmoothScrollDirective, MoveStaggerDirective, MoveTapDirective, MoveTargetDirective, MoveTextDirective, MoveTriggerDirective, MoveVariantsDirective, SmoothScrollService, SpringPlayer, WaapiPlayer, applyInitialStyles, clearComposedStyle, clearInitialStyles, composeTransitionKeyframes, isValidScrollOffset, moveIconBounce, moveIconPulse, moveIconRotate, moveIconShake, movePathDraw, prefersReducedMotion, provideMovement, resolveMoveFrames, resolveMovementConfig, reverseFrames, validateDragElastic, validateSpring };
2580
2979
  //# sourceMappingURL=angular-movement.mjs.map