motion 12.13.0 → 12.15.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.
@@ -3348,6 +3348,152 @@
3348
3348
  // "background-color"
3349
3349
  ]);
3350
3350
 
3351
+ function camelToDash$1(str) {
3352
+ return str.replace(/([A-Z])/g, (match) => `-${match.toLowerCase()}`);
3353
+ }
3354
+
3355
+ function resolveElements(elementOrSelector, scope, selectorCache) {
3356
+ if (elementOrSelector instanceof EventTarget) {
3357
+ return [elementOrSelector];
3358
+ }
3359
+ else if (typeof elementOrSelector === "string") {
3360
+ let root = document;
3361
+ if (scope) {
3362
+ root = scope.current;
3363
+ }
3364
+ const elements = selectorCache?.[elementOrSelector] ??
3365
+ root.querySelectorAll(elementOrSelector);
3366
+ return elements ? Array.from(elements) : [];
3367
+ }
3368
+ return Array.from(elementOrSelector);
3369
+ }
3370
+
3371
+ function createSelectorEffect(subjectEffect) {
3372
+ return (subject, values) => {
3373
+ const elements = resolveElements(subject);
3374
+ const subscriptions = [];
3375
+ for (const element of elements) {
3376
+ const remove = subjectEffect(element, values);
3377
+ subscriptions.push(remove);
3378
+ }
3379
+ return () => {
3380
+ for (const remove of subscriptions)
3381
+ remove();
3382
+ };
3383
+ };
3384
+ }
3385
+
3386
+ /**
3387
+ * Provided a value and a ValueType, returns the value as that value type.
3388
+ */
3389
+ const getValueAsType = (value, type) => {
3390
+ return type && typeof value === "number"
3391
+ ? type.transform(value)
3392
+ : value;
3393
+ };
3394
+
3395
+ class MotionValueState {
3396
+ constructor() {
3397
+ this.latest = {};
3398
+ this.values = new Map();
3399
+ }
3400
+ set(name, value, render, computed, useDefaultValueType = true) {
3401
+ const existingValue = this.values.get(name);
3402
+ if (existingValue) {
3403
+ existingValue.onRemove();
3404
+ }
3405
+ const onChange = () => {
3406
+ const v = value.get();
3407
+ if (useDefaultValueType) {
3408
+ this.latest[name] = getValueAsType(v, numberValueTypes[name]);
3409
+ }
3410
+ else {
3411
+ this.latest[name] = v;
3412
+ }
3413
+ render && frame.render(render);
3414
+ };
3415
+ onChange();
3416
+ const cancelOnChange = value.on("change", onChange);
3417
+ computed && value.addDependent(computed);
3418
+ const remove = () => {
3419
+ cancelOnChange();
3420
+ render && cancelFrame(render);
3421
+ this.values.delete(name);
3422
+ computed && value.removeDependent(computed);
3423
+ };
3424
+ this.values.set(name, { value, onRemove: remove });
3425
+ return remove;
3426
+ }
3427
+ get(name) {
3428
+ return this.values.get(name)?.value;
3429
+ }
3430
+ destroy() {
3431
+ for (const value of this.values.values()) {
3432
+ value.onRemove();
3433
+ }
3434
+ }
3435
+ }
3436
+
3437
+ function createEffect(addValue) {
3438
+ const stateCache = new WeakMap();
3439
+ const subscriptions = [];
3440
+ return (subject, values) => {
3441
+ const state = stateCache.get(subject) ?? new MotionValueState();
3442
+ stateCache.set(subject, state);
3443
+ for (const key in values) {
3444
+ const value = values[key];
3445
+ const remove = addValue(subject, state, key, value);
3446
+ subscriptions.push(remove);
3447
+ }
3448
+ return () => {
3449
+ for (const cancel of subscriptions)
3450
+ cancel();
3451
+ };
3452
+ };
3453
+ }
3454
+
3455
+ function canSetAsProperty(element, name) {
3456
+ if (!(name in element))
3457
+ return false;
3458
+ const descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(element), name) ||
3459
+ Object.getOwnPropertyDescriptor(element, name);
3460
+ // Check if it has a setter
3461
+ return descriptor && typeof descriptor.set === "function";
3462
+ }
3463
+ const addAttrValue = (element, state, key, value) => {
3464
+ const isProp = canSetAsProperty(element, key);
3465
+ const name = isProp
3466
+ ? key
3467
+ : key.startsWith("data") || key.startsWith("aria")
3468
+ ? camelToDash$1(key)
3469
+ : key;
3470
+ /**
3471
+ * Set attribute directly via property if available
3472
+ */
3473
+ const render = isProp
3474
+ ? () => {
3475
+ element[name] = state.latest[key];
3476
+ }
3477
+ : () => {
3478
+ const v = state.latest[key];
3479
+ if (v === null || v === undefined) {
3480
+ element.removeAttribute(name);
3481
+ }
3482
+ else {
3483
+ element.setAttribute(name, String(v));
3484
+ }
3485
+ };
3486
+ return state.set(key, value, render);
3487
+ };
3488
+ const attrEffect = /*@__PURE__*/ createSelectorEffect(
3489
+ /*@__PURE__*/ createEffect(addAttrValue));
3490
+
3491
+ const propEffect = /*@__PURE__*/ createEffect((subject, state, key, value) => {
3492
+ return state.set(key, value, () => {
3493
+ subject[key] = state.latest[key];
3494
+ }, undefined, false);
3495
+ });
3496
+
3351
3497
  /**
3352
3498
  * Maximum time between the value of two frames, beyond which we
3353
3499
  * assume the velocity has since been 0.
@@ -3670,106 +3816,6 @@
3670
3816
  return new MotionValue(init, options);
3671
3817
  }
3672
3818
 
3673
- function resolveElements(elementOrSelector, scope, selectorCache) {
3674
- if (elementOrSelector instanceof EventTarget) {
3675
- return [elementOrSelector];
3676
- }
3677
- else if (typeof elementOrSelector === "string") {
3678
- let root = document;
3679
- if (scope) {
3680
- root = scope.current;
3681
- }
3682
- const elements = selectorCache?.[elementOrSelector] ??
3683
- root.querySelectorAll(elementOrSelector);
3684
- return elements ? Array.from(elements) : [];
3685
- }
3686
- return Array.from(elementOrSelector);
3687
- }
3688
-
3689
- function createSelectorEffect(subjectEffect) {
3690
- return (subject, values) => {
3691
- const elements = resolveElements(subject);
3692
- const subscriptions = [];
3693
- for (const element of elements) {
3694
- const remove = subjectEffect(element, values);
3695
- subscriptions.push(remove);
3696
- }
3697
- return () => {
3698
- for (const remove of subscriptions)
3699
- remove();
3700
- };
3701
- };
3702
- }
3703
-
3704
- /**
3705
- * Provided a value and a ValueType, returns the value as that value type.
3706
- */
3707
- const getValueAsType = (value, type) => {
3708
- return type && typeof value === "number"
3709
- ? type.transform(value)
3710
- : value;
3711
- };
3712
-
3713
- class MotionValueState {
3714
- constructor() {
3715
- this.latest = {};
3716
- this.values = new Map();
3717
- }
3718
- set(name, value, render, computed, useDefaultValueType = true) {
3719
- const existingValue = this.values.get(name);
3720
- if (existingValue) {
3721
- existingValue.onRemove();
3722
- }
3723
- const onChange = () => {
3724
- const v = value.get();
3725
- if (useDefaultValueType) {
3726
- this.latest[name] = getValueAsType(v, numberValueTypes[name]);
3727
- }
3728
- else {
3729
- this.latest[name] = v;
3730
- }
3731
- render && frame.render(render);
3732
- };
3733
- onChange();
3734
- const cancelOnChange = value.on("change", onChange);
3735
- computed && value.addDependent(computed);
3736
- const remove = () => {
3737
- cancelOnChange();
3738
- render && cancelFrame(render);
3739
- this.values.delete(name);
3740
- computed && value.removeDependent(computed);
3741
- };
3742
- this.values.set(name, { value, onRemove: remove });
3743
- return remove;
3744
- }
3745
- get(name) {
3746
- return this.values.get(name)?.value;
3747
- }
3748
- destroy() {
3749
- for (const value of this.values.values()) {
3750
- value.onRemove();
3751
- }
3752
- }
3753
- }
3754
-
3755
- function createEffect(addValue) {
3756
- const stateCache = new WeakMap();
3757
- const subscriptions = [];
3758
- return (subject, values) => {
3759
- const state = stateCache.get(subject) ?? new MotionValueState();
3760
- stateCache.set(subject, state);
3761
- for (const key in values) {
3762
- const value = values[key];
3763
- const remove = addValue(subject, state, key, value);
3764
- subscriptions.push(remove);
3765
- }
3766
- return () => {
3767
- for (const cancel of subscriptions)
3768
- cancel();
3769
- };
3770
- };
3771
- }
3772
-
3773
3819
  const translateAlias$1 = {
3774
3820
  x: "translateX",
3775
3821
  y: "translateY",
@@ -3805,17 +3851,34 @@
3805
3851
  return transformIsDefault ? "none" : transform.trim();
3806
3852
  }
3807
3853
 
3854
+ const originProps = new Set(["originX", "originY", "originZ"]);
3808
3855
  const addStyleValue = (element, state, key, value) => {
3809
3856
  let render = undefined;
3810
3857
  let computed = undefined;
3811
3858
  if (transformProps.has(key)) {
3812
3859
  if (!state.get("transform")) {
3860
+ // If this is an HTML element, we need to set the transform-box to fill-box
3861
+ // to normalise the transform relative to the element's bounding box
3862
+ if (!isHTMLElement(element) && !state.get("transformBox")) {
3863
+ addStyleValue(element, state, "transformBox", new MotionValue("fill-box"));
3864
+ }
3813
3865
  state.set("transform", new MotionValue("none"), () => {
3814
3866
  element.style.transform = buildTransform$1(state);
3815
3867
  });
3816
3868
  }
3817
3869
  computed = state.get("transform");
3818
3870
  }
3871
+ else if (originProps.has(key)) {
3872
+ if (!state.get("transformOrigin")) {
3873
+ state.set("transformOrigin", new MotionValue(""), () => {
3874
+ const originX = state.latest.originX ?? "50%";
3875
+ const originY = state.latest.originY ?? "50%";
3876
+ const originZ = state.latest.originZ ?? 0;
3877
+ element.style.transformOrigin = `${originX} ${originY} ${originZ}`;
3878
+ });
3879
+ }
3880
+ computed = state.get("transformOrigin");
3881
+ }
3819
3882
  else if (isCSSVar(key)) {
3820
3883
  render = () => {
3821
3884
  element.style.setProperty(key, state.latest[key]);
@@ -3828,7 +3891,40 @@
3828
3891
  }
3829
3892
  return state.set(key, value, render, computed);
3830
3893
  };
3831
- const styleEffect = createSelectorEffect(createEffect(addStyleValue));
3894
+ const styleEffect = /*@__PURE__*/ createSelectorEffect(
3895
+ /*@__PURE__*/ createEffect(addStyleValue));
3896
+
3897
+ const toPx = px.transform;
3898
+ function addSVGPathValue(element, state, key, value) {
3899
+ frame.render(() => element.setAttribute("pathLength", "1"));
3900
+ if (key === "pathOffset") {
3901
+ return state.set(key, value, () => element.setAttribute("stroke-dashoffset", toPx(-state.latest[key])));
3902
+ }
3903
+ else {
3904
+ if (!state.get("stroke-dasharray")) {
3905
+ state.set("stroke-dasharray", new MotionValue("1 1"), () => {
3906
+ const { pathLength = 1, pathSpacing } = state.latest;
3907
+ element.setAttribute("stroke-dasharray", `${toPx(pathLength)} ${toPx(pathSpacing ?? 1 - Number(pathLength))}`);
3908
+ });
3909
+ }
3910
+ return state.set(key, value, undefined, state.get("stroke-dasharray"));
3911
+ }
3912
+ }
3913
+ const addSVGValue = (element, state, key, value) => {
3914
+ if (key.startsWith("path")) {
3915
+ return addSVGPathValue(element, state, key, value);
3916
+ }
3917
+ else if (key.startsWith("attr")) {
3918
+ return addAttrValue(element, state, convertAttrKey(key), value);
3919
+ }
3920
+ const handler = key in element.style ? addStyleValue : addAttrValue;
3921
+ return handler(element, state, key, value);
3922
+ };
3923
+ const svgEffect = /*@__PURE__*/ createSelectorEffect(
3924
+ /*@__PURE__*/ createEffect(addSVGValue));
3925
+ function convertAttrKey(key) {
3926
+ return key.replace(/^attr([A-Z])/, (_, firstChar) => firstChar.toLowerCase());
3927
+ }
3832
3928
 
3833
3929
  const { schedule: microtask, cancel: cancelMicrotask } =
3834
3930
  /* @__PURE__ */ createRenderBatcher(queueMicrotask, false);
@@ -7277,6 +7373,7 @@
7277
7373
  exports.ViewTransitionBuilder = ViewTransitionBuilder;
7278
7374
  exports.acceleratedValues = acceleratedValues;
7279
7375
  exports.activeAnimations = activeAnimations;
7376
+ exports.addAttrValue = addAttrValue;
7280
7377
  exports.addStyleValue = addStyleValue;
7281
7378
  exports.addUniqueItem = addUniqueItem;
7282
7379
  exports.alpha = alpha;
@@ -7289,6 +7386,7 @@
7289
7386
  exports.anticipate = anticipate;
7290
7387
  exports.applyPxDefaults = applyPxDefaults;
7291
7388
  exports.attachSpring = attachSpring;
7389
+ exports.attrEffect = attrEffect;
7292
7390
  exports.backIn = backIn;
7293
7391
  exports.backInOut = backInOut;
7294
7392
  exports.backOut = backOut;
@@ -7397,6 +7495,7 @@
7397
7495
  exports.press = press;
7398
7496
  exports.progress = progress;
7399
7497
  exports.progressPercentage = progressPercentage;
7498
+ exports.propEffect = propEffect;
7400
7499
  exports.px = px;
7401
7500
  exports.readTransformValue = readTransformValue;
7402
7501
  exports.recordStats = recordStats;
@@ -7424,6 +7523,7 @@
7424
7523
  exports.supportsLinearEasing = supportsLinearEasing;
7425
7524
  exports.supportsPartialKeyframes = supportsPartialKeyframes;
7426
7525
  exports.supportsScrollTimeline = supportsScrollTimeline;
7526
+ exports.svgEffect = svgEffect;
7427
7527
  exports.sync = sync;
7428
7528
  exports.testValueType = testValueType;
7429
7529
  exports.time = time;