@jsenv/dom 0.6.0 → 0.7.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.
Files changed (109) hide show
  1. package/dist/jsenv_dom.js +262 -330
  2. package/package.json +2 -4
  3. package/index.js +0 -124
  4. package/src/attr/add_attribute_effect.js +0 -93
  5. package/src/attr/attributes.js +0 -32
  6. package/src/color/color_constrast.js +0 -69
  7. package/src/color/color_parsing.js +0 -319
  8. package/src/color/color_scheme.js +0 -28
  9. package/src/color/pick_light_or_dark.js +0 -34
  10. package/src/color/resolve_css_color.js +0 -60
  11. package/src/demos/3_columns_resize_demo.html +0 -84
  12. package/src/demos/3_rows_resize_demo.html +0 -89
  13. package/src/demos/aside_and_main_demo.html +0 -93
  14. package/src/demos/coordinates_demo.html +0 -450
  15. package/src/demos/document_autoscroll_demo.html +0 -517
  16. package/src/demos/drag_gesture_constraints_demo.html +0 -701
  17. package/src/demos/drag_gesture_demo.html +0 -1047
  18. package/src/demos/drag_gesture_element_to_impact_demo.html +0 -445
  19. package/src/demos/drag_reference_element_demo.html +0 -480
  20. package/src/demos/flex_details_set_demo.html +0 -302
  21. package/src/demos/flex_details_set_demo_2.html +0 -315
  22. package/src/demos/visible_rect_demo.html +0 -525
  23. package/src/element_signature.js +0 -100
  24. package/src/interaction/drag/constraint_feedback_line.js +0 -92
  25. package/src/interaction/drag/drag_constraint.js +0 -659
  26. package/src/interaction/drag/drag_debug_markers.js +0 -635
  27. package/src/interaction/drag/drag_element_positioner.js +0 -382
  28. package/src/interaction/drag/drag_gesture.js +0 -566
  29. package/src/interaction/drag/drag_resize_demo.html +0 -571
  30. package/src/interaction/drag/drag_to_move.js +0 -301
  31. package/src/interaction/drag/drag_to_resize_gesture.js +0 -68
  32. package/src/interaction/drag/drop_target_detection.js +0 -148
  33. package/src/interaction/drag/sticky_frontiers.js +0 -160
  34. package/src/interaction/event_marker.js +0 -14
  35. package/src/interaction/focus/active_element.js +0 -33
  36. package/src/interaction/focus/arrow_navigation.js +0 -599
  37. package/src/interaction/focus/element_is_focusable.js +0 -57
  38. package/src/interaction/focus/element_visibility.js +0 -111
  39. package/src/interaction/focus/find_focusable.js +0 -21
  40. package/src/interaction/focus/focus_group.js +0 -91
  41. package/src/interaction/focus/focus_group_registry.js +0 -12
  42. package/src/interaction/focus/focus_nav.js +0 -12
  43. package/src/interaction/focus/focus_nav_event_marker.js +0 -14
  44. package/src/interaction/focus/focus_trap.js +0 -105
  45. package/src/interaction/focus/tab_navigation.js +0 -128
  46. package/src/interaction/focus/tests/focus_group_skip_tab_test.html +0 -206
  47. package/src/interaction/focus/tests/tree_focus_test.html +0 -304
  48. package/src/interaction/focus/tests/tree_focus_test.jsx +0 -261
  49. package/src/interaction/focus/tests/tree_focus_test_preact.html +0 -13
  50. package/src/interaction/isolate_interactions.js +0 -161
  51. package/src/interaction/keyboard.js +0 -26
  52. package/src/interaction/scroll/capture_scroll.js +0 -47
  53. package/src/interaction/scroll/is_scrollable.js +0 -159
  54. package/src/interaction/scroll/scroll_container.js +0 -110
  55. package/src/interaction/scroll/scroll_trap.js +0 -44
  56. package/src/interaction/scroll/scrollbar_size.js +0 -20
  57. package/src/interaction/scroll/wheel_through.js +0 -138
  58. package/src/iterable_weak_set.js +0 -66
  59. package/src/position/dom_coords.js +0 -340
  60. package/src/position/offset_parent.js +0 -15
  61. package/src/position/position_fixed.js +0 -15
  62. package/src/position/position_sticky.js +0 -213
  63. package/src/position/sticky_rect.js +0 -79
  64. package/src/position/visible_rect.js +0 -486
  65. package/src/pub_sub.js +0 -31
  66. package/src/size/can_take_size.js +0 -11
  67. package/src/size/details_content_full_height.js +0 -63
  68. package/src/size/flex_details_set.js +0 -974
  69. package/src/size/get_available_height.js +0 -22
  70. package/src/size/get_available_width.js +0 -22
  71. package/src/size/get_border_sizes.js +0 -14
  72. package/src/size/get_height.js +0 -4
  73. package/src/size/get_inner_height.js +0 -15
  74. package/src/size/get_inner_width.js +0 -15
  75. package/src/size/get_margin_sizes.js +0 -10
  76. package/src/size/get_max_height.js +0 -57
  77. package/src/size/get_max_width.js +0 -47
  78. package/src/size/get_min_height.js +0 -14
  79. package/src/size/get_min_width.js +0 -14
  80. package/src/size/get_padding_sizes.js +0 -10
  81. package/src/size/get_width.js +0 -4
  82. package/src/size/hooks/use_available_height.js +0 -27
  83. package/src/size/hooks/use_available_width.js +0 -27
  84. package/src/size/hooks/use_max_height.js +0 -10
  85. package/src/size/hooks/use_max_width.js +0 -10
  86. package/src/size/hooks/use_resize_status.js +0 -62
  87. package/src/size/resize.js +0 -695
  88. package/src/size/resolve_css_size.js +0 -32
  89. package/src/style/dom_styles.js +0 -97
  90. package/src/style/style_composition.js +0 -121
  91. package/src/style/style_controller.js +0 -345
  92. package/src/style/style_default.js +0 -153
  93. package/src/style/style_default_demo.html +0 -128
  94. package/src/style/style_parsing.js +0 -375
  95. package/src/transition/demos/animation_resumption_test.xhtml +0 -500
  96. package/src/transition/demos/height_toggle_test.xhtml +0 -515
  97. package/src/transition/dom_transition.js +0 -254
  98. package/src/transition/easing.js +0 -48
  99. package/src/transition/group_transition.js +0 -261
  100. package/src/transition/transform_style_parser.js +0 -32
  101. package/src/transition/transition_playback.js +0 -366
  102. package/src/transition/transition_timeline.js +0 -79
  103. package/src/traversal.js +0 -247
  104. package/src/ui_transition/demos/content_states_transition_demo.html +0 -628
  105. package/src/ui_transition/demos/smooth_height_transition_demo.html +0 -149
  106. package/src/ui_transition/demos/transition_testing.html +0 -354
  107. package/src/ui_transition/ui_transition.js +0 -1491
  108. package/src/utils.js +0 -69
  109. package/src/value_effect.js +0 -35
package/dist/jsenv_dom.js CHANGED
@@ -61,6 +61,16 @@ import { useState, useLayoutEffect } from "preact/hooks";
61
61
  * getElementSignature(null) // Returns: "null"
62
62
  */
63
63
  const getElementSignature = (element) => {
64
+ if (Array.isArray(element)) {
65
+ if (element.length === 0) {
66
+ return "empty";
67
+ }
68
+ if (element.length === 1) {
69
+ return getElementSignature(element[0]);
70
+ }
71
+ const parent = element[0].parentNode;
72
+ return `${getElementSignature(parent)} children`;
73
+ }
64
74
  if (!element) {
65
75
  return String(element);
66
76
  }
@@ -306,11 +316,13 @@ const getAssociatedElements = (element) => {
306
316
  return null;
307
317
  };
308
318
 
309
- const getComputedStyle$1 = (element) =>
310
- elementToOwnerWindow(element).getComputedStyle(element);
319
+ const getComputedStyle$1 = (element) => {
320
+ return elementToOwnerWindow(element).getComputedStyle(element);
321
+ };
311
322
 
312
- const getStyle = (element, name) =>
313
- getComputedStyle$1(element).getPropertyValue(name);
323
+ const getStyle = (element, name) => {
324
+ return getComputedStyle$1(element).getPropertyValue(name);
325
+ };
314
326
  const setStyle = (element, name, value) => {
315
327
 
316
328
  const prevValue = element.style[name];
@@ -487,7 +499,11 @@ const normalizeStyle = (value, propertyName, context = "js") => {
487
499
  // If value is a CSS transform string, parse it first to extract the specific property
488
500
  if (typeof value === "string") {
489
501
  if (value === "none") {
490
- return undefined;
502
+ if (transformProperty.startsWith("scale")) {
503
+ return 1;
504
+ }
505
+ // translate, rotate, skew
506
+ return 0;
491
507
  }
492
508
  const parsedTransform = parseCSSTransform(value);
493
509
  return parsedTransform?.[transformProperty];
@@ -501,38 +517,55 @@ const normalizeStyle = (value, propertyName, context = "js") => {
501
517
  }
502
518
 
503
519
  if (pxProperties.includes(propertyName)) {
504
- return normalizeNumber(value, context, "px", propertyName);
520
+ return normalizeNumber(value, {
521
+ propertyName,
522
+ unit: "px",
523
+ preferedType: context === "js" ? "number" : "string",
524
+ });
505
525
  }
506
526
  if (degProperties.includes(propertyName)) {
507
- return normalizeNumber(value, context, "deg", propertyName);
527
+ return normalizeNumber(value, {
528
+ propertyName,
529
+ unit: "deg",
530
+ preferedType: "string",
531
+ });
508
532
  }
509
533
  if (unitlessProperties.includes(propertyName)) {
510
- return normalizeNumber(value, context, "", propertyName);
534
+ return normalizeNumber(value, {
535
+ propertyName,
536
+ unit: "",
537
+ preferedType: context === "js" ? "number" : "string",
538
+ });
511
539
  }
512
540
 
513
541
  return value;
514
542
  };
515
- const normalizeNumber = (value, context, unit, propertyName) => {
516
- if (context === "css") {
517
- if (typeof value === "number") {
518
- if (isNaN(value)) {
519
- console.warn(`NaN found for "${propertyName}"`);
520
- }
521
- return `${value}${unit}`;
522
- }
523
- return value;
524
- }
543
+ const normalizeNumber = (value, { unit, propertyName, preferedType }) => {
525
544
  if (typeof value === "string") {
526
- // For js context, only convert px values to numbers
527
- if (unit === "px" && value.endsWith("px")) {
545
+ // Keep strings as-is (including %, em, rem, auto, none, etc.)
546
+ if (preferedType === "string") {
547
+ return value;
548
+ }
549
+ // convert to number if possible (font-size: "12px" -> fontSize:12, opacity: "0.5" -> opacity: 0.5)
550
+ if (!unit || value.endsWith(unit)) {
528
551
  const numericValue = parseFloat(value);
529
552
  if (!isNaN(numericValue)) {
530
553
  return numericValue;
531
554
  }
532
555
  }
533
- // Keep all other strings as-is (including %, em, rem, auto, none, etc.)
534
556
  return value;
535
557
  }
558
+ if (typeof value === "number") {
559
+ if (isNaN(value)) {
560
+ console.warn(`NaN found for "${propertyName}"`);
561
+ }
562
+ if (preferedType === "number") {
563
+ return value;
564
+ }
565
+ // convert to string with unit
566
+ return `${value}${unit}`;
567
+ }
568
+
536
569
  return value;
537
570
  };
538
571
 
@@ -958,6 +991,21 @@ const onElementControllerRemoved = (element, controller) => {
958
991
  }
959
992
  };
960
993
 
994
+ /**
995
+ * Creates a style controller that can safely manage CSS styles on DOM elements.
996
+ *
997
+ * Uses Web Animations API to override styles without touching inline styles,
998
+ * allowing multiple controllers to work together and providing intelligent transform composition.
999
+ *
1000
+ * @param {string} [name="anonymous"] - Debug name for the controller
1001
+ * @returns {Object} Controller with methods: set, get, delete, getUnderlyingValue, commit, clear, clearAll
1002
+ *
1003
+ * @example
1004
+ * const controller = createStyleController("myFeature");
1005
+ * controller.set(element, { opacity: 0.5, transform: { translateX: 100 } });
1006
+ * controller.getUnderlyingValue(element, "opacity"); // Read value without controller influence
1007
+ * controller.clearAll(); // Cleanup
1008
+ */
961
1009
  const createStyleController = (name = "anonymous") => {
962
1010
  // Store element data for this controller: element -> { styles, animation }
963
1011
  const elementWeakMap = new WeakMap();
@@ -1014,11 +1062,27 @@ const createStyleController = (name = "anonymous") => {
1014
1062
  return;
1015
1063
  }
1016
1064
  const { styles, animation } = elementData;
1017
- const hasStyle = Object.hasOwn(styles, propertyName);
1018
- if (!hasStyle) {
1019
- return;
1065
+ if (propertyName.startsWith("transform.")) {
1066
+ const transformProp = propertyName.slice("transform.".length);
1067
+ const transformObject = styles.transform;
1068
+ if (!transformObject) {
1069
+ return;
1070
+ }
1071
+ const hasTransformProp = Object.hasOwn(transformObject, transformProp);
1072
+ if (!hasTransformProp) {
1073
+ return;
1074
+ }
1075
+ delete transformObject[transformProp];
1076
+ if (Object.keys(transformObject).length === 0) {
1077
+ delete styles.transform;
1078
+ }
1079
+ } else {
1080
+ const hasStyle = Object.hasOwn(styles, propertyName);
1081
+ if (!hasStyle) {
1082
+ return;
1083
+ }
1084
+ delete styles[propertyName];
1020
1085
  }
1021
- delete styles[propertyName];
1022
1086
  const isEmpty = Object.keys(styles).length === 0;
1023
1087
  // Clean up empty controller
1024
1088
  if (isEmpty) {
@@ -1220,6 +1284,44 @@ const updateAnimationStyles = (animation, styles) => {
1220
1284
  animation.pause();
1221
1285
  };
1222
1286
 
1287
+ const dormantStyleController = createStyleController("dormant");
1288
+ const getOpacity = (
1289
+ element,
1290
+ styleControllerToIgnore = dormantStyleController,
1291
+ ) => {
1292
+ return styleControllerToIgnore.getUnderlyingValue(element, "opacity");
1293
+ };
1294
+ const getTranslateX = (
1295
+ element,
1296
+ styleControllerToIgnore = dormantStyleController,
1297
+ ) => {
1298
+ return styleControllerToIgnore.getUnderlyingValue(
1299
+ element,
1300
+ "transform.translateX",
1301
+ );
1302
+ };
1303
+ const getTranslateY = (
1304
+ element,
1305
+ styleControllerToIgnore = dormantStyleController,
1306
+ ) => {
1307
+ return styleControllerToIgnore.getUnderlyingValue(
1308
+ element,
1309
+ "transform.translateY",
1310
+ );
1311
+ };
1312
+ const getWidth$1 = (
1313
+ element,
1314
+ styleControllerToIgnore = dormantStyleController,
1315
+ ) => {
1316
+ return styleControllerToIgnore.getUnderlyingValue(element, "rect.width");
1317
+ };
1318
+ const getHeight$1 = (
1319
+ element,
1320
+ styleControllerToIgnore = dormantStyleController,
1321
+ ) => {
1322
+ return styleControllerToIgnore.getUnderlyingValue(element, "rect.height");
1323
+ };
1324
+
1223
1325
  // Register the style isolator custom element once
1224
1326
  let persistentStyleIsolator = null;
1225
1327
  const getNaviStyleIsolator = () => {
@@ -7990,32 +8092,6 @@ const pickPositionRelativeTo = (
7990
8092
  };
7991
8093
  };
7992
8094
 
7993
- const parseTransform = (transform) => {
7994
- if (!transform || transform === "none") return new Map();
7995
- const transformMap = new Map();
7996
-
7997
- if (transform.startsWith("matrix(")) {
7998
- // matrix(a, b, c, d, e, f) where e is translateX and f is translateY
7999
- const values = transform
8000
- .match(/matrix\((.*?)\)/)?.[1]
8001
- .split(",")
8002
- .map(Number);
8003
- if (values) {
8004
- const translateX = values[4]; // e value from matrix
8005
- transformMap.set("translateX", { value: translateX, unit: "px" });
8006
- return transformMap;
8007
- }
8008
- }
8009
-
8010
- // For direct transform functions (when set via style.transform)
8011
- const matches = transform.matchAll(/(\w+)\(([-\d.]+)(%|px|deg)?\)/g);
8012
- for (const match of matches) {
8013
- const [, func, value, unit = ""] = match;
8014
- transformMap.set(func, { value: parseFloat(value), unit });
8015
- }
8016
- return transformMap;
8017
- };
8018
-
8019
8095
  const EASING = {
8020
8096
  LINEAR: (x) => x,
8021
8097
  EASE: (x) => {
@@ -8493,25 +8569,7 @@ const createCallbackController = () => {
8493
8569
  return [callbacks, execute];
8494
8570
  };
8495
8571
 
8496
- installImportMetaCss(import.meta);
8497
- import.meta.css = /* css */ `
8498
- /* Transition data attributes override inline styles using CSS custom properties */
8499
- *[data-transition-opacity] {
8500
- opacity: var(--ui-transition-opacity) !important;
8501
- }
8502
-
8503
- *[data-transition-translate-x] {
8504
- transform: translateX(var(--ui-transition-translate-x)) !important;
8505
- }
8506
-
8507
- *[data-transition-width] {
8508
- width: var(--ui-transition-width) !important;
8509
- }
8510
-
8511
- *[data-transition-height] {
8512
- height: var(--ui-transition-height) !important;
8513
- }
8514
- `;
8572
+ const transitionStyleController = createStyleController("transition");
8515
8573
 
8516
8574
  const createHeightTransition = (element, to, options) => {
8517
8575
  const heightTransition = createTimelineTransition({
@@ -8523,22 +8581,16 @@ const createHeightTransition = (element, to, options) => {
8523
8581
  minDiff: 10,
8524
8582
  lifecycle: {
8525
8583
  setup: () => {
8526
- const restoreWillChange = addWillChange(element, "height");
8527
8584
  return {
8528
- from: getHeight(element),
8585
+ from: getHeight$1(element),
8529
8586
  update: ({ value }) => {
8530
- const valueWithUnit = `${value}px`;
8531
- element.setAttribute("data-transition-height", valueWithUnit);
8532
- element.style.setProperty("--ui-transition-height", valueWithUnit);
8587
+ transitionStyleController.set(element, { height: value });
8533
8588
  },
8534
8589
  teardown: () => {
8535
- element.removeAttribute("data-transition-height");
8536
- element.style.removeProperty("--ui-transition-height");
8537
- restoreWillChange();
8590
+ transitionStyleController.delete(element, "height");
8538
8591
  },
8539
8592
  restore: () => {
8540
- element.removeAttribute("data-transition-height");
8541
- element.style.removeProperty("--ui-transition-height");
8593
+ transitionStyleController.delete(element, "height");
8542
8594
  },
8543
8595
  };
8544
8596
  },
@@ -8556,22 +8608,16 @@ const createWidthTransition = (element, to, options) => {
8556
8608
  isVisual: true,
8557
8609
  lifecycle: {
8558
8610
  setup: () => {
8559
- const restoreWillChange = addWillChange(element, "width");
8560
8611
  return {
8561
- from: getWidth(element),
8612
+ from: getWidth$1(element),
8562
8613
  update: ({ value }) => {
8563
- const valueWithUnit = `${value}px`;
8564
- element.setAttribute("data-transition-width", valueWithUnit);
8565
- element.style.setProperty("--ui-transition-width", valueWithUnit);
8614
+ transitionStyleController.set(element, { width: value });
8566
8615
  },
8567
8616
  teardown: () => {
8568
- element.removeAttribute("data-transition-width");
8569
- element.style.removeProperty("--ui-transition-width");
8570
- restoreWillChange();
8617
+ transitionStyleController.delete(element, "width");
8571
8618
  },
8572
8619
  restore: () => {
8573
- element.removeAttribute("data-transition-width");
8574
- element.style.removeProperty("--ui-transition-width");
8620
+ transitionStyleController.delete(element, "width");
8575
8621
  },
8576
8622
  };
8577
8623
  },
@@ -8589,21 +8635,16 @@ const createOpacityTransition = (element, to, options = {}) => {
8589
8635
  isVisual: true,
8590
8636
  lifecycle: {
8591
8637
  setup: () => {
8592
- const restoreWillChange = addWillChange(element, "opacity");
8593
8638
  return {
8594
8639
  from: getOpacity(element),
8595
8640
  update: ({ value }) => {
8596
- element.setAttribute("data-transition-opacity", value);
8597
- element.style.setProperty("--ui-transition-opacity", value);
8641
+ transitionStyleController.set(element, { opacity: value });
8598
8642
  },
8599
8643
  teardown: () => {
8600
- element.removeAttribute("data-transition-opacity");
8601
- element.style.removeProperty("--ui-transition-opacity");
8602
- restoreWillChange();
8644
+ transitionStyleController.delete(element, "opacity");
8603
8645
  },
8604
8646
  restore: () => {
8605
- element.removeAttribute("data-transition-opacity");
8606
- element.style.removeProperty("--ui-transition-opacity");
8647
+ transitionStyleController.delete(element, "opacity");
8607
8648
  },
8608
8649
  };
8609
8650
  },
@@ -8611,19 +8652,8 @@ const createOpacityTransition = (element, to, options = {}) => {
8611
8652
  });
8612
8653
  return opacityTransition;
8613
8654
  };
8614
- const getOpacity = (element) => {
8615
- return parseFloat(getComputedStyle(element).opacity) || 0;
8616
- };
8617
8655
 
8618
8656
  const createTranslateXTransition = (element, to, options) => {
8619
- let unit = "px";
8620
- if (typeof to === "string") {
8621
- if (to.endsWith("%")) {
8622
- unit = "%";
8623
- }
8624
- to = parseFloat(to);
8625
- }
8626
-
8627
8657
  const translateXTransition = createTimelineTransition({
8628
8658
  ...options,
8629
8659
  constructor: createTranslateXTransition,
@@ -8633,25 +8663,20 @@ const createTranslateXTransition = (element, to, options) => {
8633
8663
  isVisual: true,
8634
8664
  lifecycle: {
8635
8665
  setup: () => {
8636
- const restoreWillChange = addWillChange(element, "transform");
8637
8666
  return {
8638
8667
  from: getTranslateX(element),
8639
8668
  update: ({ value }) => {
8640
- const valueWithUnit = `${value}${unit}`;
8641
- element.setAttribute("data-transition-translate-x", valueWithUnit);
8642
- element.style.setProperty(
8643
- "--ui-transition-translate-x",
8644
- valueWithUnit,
8645
- );
8669
+ transitionStyleController.set(element, {
8670
+ transform: {
8671
+ translateX: value,
8672
+ },
8673
+ });
8646
8674
  },
8647
8675
  teardown: () => {
8648
- restoreWillChange();
8649
- element.removeAttribute("data-transition-translate-x");
8650
- element.style.removeProperty("--ui-transition-translate-x");
8676
+ transitionStyleController.delete(element, "transform.translateX");
8651
8677
  },
8652
8678
  restore: () => {
8653
- element.removeAttribute("data-transition-translate-x");
8654
- element.style.removeProperty("--ui-transition-translate-x");
8679
+ transitionStyleController.delete(element, "transform.translateX");
8655
8680
  },
8656
8681
  };
8657
8682
  },
@@ -8659,48 +8684,12 @@ const createTranslateXTransition = (element, to, options) => {
8659
8684
  });
8660
8685
  return translateXTransition;
8661
8686
  };
8662
- const getTranslateX = (element) => {
8663
- const transform = getComputedStyle(element).transform;
8664
- const transformMap = parseTransform(transform);
8665
- return transformMap.get("translateX")?.value || 0;
8666
- };
8667
-
8668
- // Helper functions for getting natural (non-transition) values
8669
- const getOpacityWithoutTransition = (element) => {
8670
- const transitionOpacity = element.getAttribute("data-transition-opacity");
8671
-
8672
- // Temporarily remove transition attribute
8673
- element.removeAttribute("data-transition-opacity");
8674
8687
 
8675
- const naturalValue = parseFloat(getComputedStyle(element).opacity) || 0;
8676
-
8677
- // Restore transition attribute if it existed
8678
- if (transitionOpacity !== null) {
8679
- element.setAttribute("data-transition-opacity", transitionOpacity);
8680
- }
8681
-
8682
- return naturalValue;
8683
- };
8684
-
8685
- const getTranslateXWithoutTransition = (element) => {
8686
- const transitionTranslateX = element.getAttribute(
8687
- "data-transition-translate-x",
8688
- );
8689
-
8690
- // Temporarily remove transition attribute
8691
- element.removeAttribute("data-transition-translate-x");
8692
-
8693
- const transform = getComputedStyle(element).transform;
8694
- const transformMap = parseTransform(transform);
8695
- const naturalValue = transformMap.get("translateX")?.value || 0;
8696
-
8697
- // Restore transition attribute if it existed
8698
- if (transitionTranslateX !== null) {
8699
- element.setAttribute("data-transition-translate-x", transitionTranslateX);
8700
- }
8701
-
8702
- return naturalValue;
8703
- };
8688
+ // Helper functions for getting natural values
8689
+ const getOpacityWithoutTransition = (element) =>
8690
+ getOpacity(element, transitionStyleController);
8691
+ const getTranslateXWithoutTransition = (element) =>
8692
+ getTranslateX(element, transitionStyleController);
8704
8693
 
8705
8694
  // transition that manages multiple transitions
8706
8695
  const createGroupTransition = (transitionArray) => {
@@ -10287,34 +10276,27 @@ const useResizeStatus = (elementRef, { as = "number" } = {}) => {
10287
10276
 
10288
10277
  installImportMetaCss(import.meta);
10289
10278
  import.meta.css = /* css */ `
10290
- .ui_transition_container {
10291
- position: relative;
10292
- display: inline-flex;
10293
- flex: 1;
10294
- }
10295
-
10296
- .ui_transition_outer_wrapper {
10279
+ .ui_transition_container,
10280
+ .ui_transition_outer_wrapper,
10281
+ .ui_transition_measure_wrapper,
10282
+ .ui_transition_slot,
10283
+ .ui_transition_phase_overlay,
10284
+ .ui_transition_content_overlay {
10297
10285
  display: inline-flex;
10298
- flex: 1;
10286
+ width: 100%;
10287
+ height: 100%;
10299
10288
  }
10300
10289
 
10301
- .ui_transition_measure_wrapper {
10302
- display: inline-flex;
10303
- flex: 1;
10290
+ .ui_transition_measure_wrapper[data-transition-translate-x] {
10291
+ overflow: hidden;
10304
10292
  }
10305
10293
 
10294
+ .ui_transition_container,
10306
10295
  .ui_transition_slot {
10307
10296
  position: relative;
10308
- display: inline-flex;
10309
- flex: 1;
10310
- }
10311
-
10312
- .ui_transition_phase_overlay {
10313
- position: absolute;
10314
- inset: 0;
10315
- pointer-events: none;
10316
10297
  }
10317
10298
 
10299
+ .ui_transition_phase_overlay,
10318
10300
  .ui_transition_content_overlay {
10319
10301
  position: absolute;
10320
10302
  inset: 0;
@@ -10329,11 +10311,15 @@ const DEBUG = {
10329
10311
  };
10330
10312
 
10331
10313
  // Utility function to format content key states consistently for debug logs
10332
- const formatContentKeyState = (contentKey, hasChild, hasTextNode = false) => {
10314
+ const formatContentKeyState = (
10315
+ contentKey,
10316
+ hasChildren,
10317
+ hasTextNode = false,
10318
+ ) => {
10333
10319
  if (hasTextNode) {
10334
10320
  return "[text]";
10335
10321
  }
10336
- if (!hasChild) {
10322
+ if (!hasChildren) {
10337
10323
  return "[empty]";
10338
10324
  }
10339
10325
  if (contentKey === null || contentKey === undefined) {
@@ -10354,6 +10340,7 @@ const initUITransition = (container) => {
10354
10340
  ...DEBUG,
10355
10341
  transition: container.hasAttribute("data-debug-transition"),
10356
10342
  };
10343
+ const debugClones = container.hasAttribute("data-debug-clones");
10357
10344
 
10358
10345
  const debug = (type, ...args) => {
10359
10346
  if (localDebug[type]) {
@@ -10378,17 +10365,6 @@ const initUITransition = (container) => {
10378
10365
  ".ui_transition_content_overlay",
10379
10366
  );
10380
10367
 
10381
- if (!phaseOverlay) {
10382
- phaseOverlay = document.createElement("div");
10383
- phaseOverlay.className = "ui_transition_phase_overlay";
10384
- measureWrapper.appendChild(phaseOverlay);
10385
- }
10386
- if (!contentOverlay) {
10387
- contentOverlay = document.createElement("div");
10388
- contentOverlay.className = "ui_transition_content_overlay";
10389
- container.appendChild(contentOverlay);
10390
- }
10391
-
10392
10368
  if (
10393
10369
  !outerWrapper ||
10394
10370
  !measureWrapper ||
@@ -10431,7 +10407,7 @@ const initUITransition = (container) => {
10431
10407
 
10432
10408
  // Child state
10433
10409
  let lastContentKey = null;
10434
- let previousChild = null;
10410
+ let previousChildNodes = [];
10435
10411
  let isContentPhase = false; // Current state: true when showing content phase (loading/error)
10436
10412
  let wasContentPhase = false; // Previous state for comparison
10437
10413
 
@@ -10660,40 +10636,48 @@ const initUITransition = (container) => {
10660
10636
  const setupTransition = ({
10661
10637
  isPhaseTransition = false,
10662
10638
  overlay,
10663
- existingOldContents,
10664
- needsOldChildClone,
10665
- previousChild,
10666
- firstChild,
10639
+ needsOldChildNodesClone,
10640
+ previousChildNodes,
10641
+ childNodes,
10667
10642
  attributeToRemove = [],
10668
10643
  }) => {
10669
- let oldChild = null;
10670
10644
  let cleanup = () => {};
10671
- const currentTransitionElement = existingOldContents[0];
10645
+ let elementToImpact;
10672
10646
 
10673
- if (currentTransitionElement) {
10674
- oldChild = currentTransitionElement;
10647
+ if (overlay.childNodes.length > 0) {
10648
+ elementToImpact = overlay;
10649
+ cleanup = () => {
10650
+ if (!debugClones) {
10651
+ overlay.innerHTML = "";
10652
+ }
10653
+ };
10675
10654
  debug(
10676
10655
  "transition",
10677
10656
  `Continuing from current ${isPhaseTransition ? "phase" : "content"} transition element`,
10678
10657
  );
10679
- cleanup = () => oldChild.remove();
10680
- } else if (needsOldChildClone) {
10658
+ } else if (needsOldChildNodesClone) {
10681
10659
  overlay.innerHTML = "";
10682
-
10683
- // Clone the individual element for the transition
10684
- oldChild = previousChild.cloneNode(true);
10685
-
10686
- // Remove specified attributes
10687
- attributeToRemove.forEach((attr) => oldChild.removeAttribute(attr));
10688
-
10689
- oldChild.setAttribute("data-ui-transition-old", "");
10690
- overlay.appendChild(oldChild);
10660
+ for (const previousChildNode of previousChildNodes) {
10661
+ const previousChildClone = previousChildNode.cloneNode(true);
10662
+ if (previousChildClone.nodeType !== Node.TEXT_NODE) {
10663
+ for (const attrToRemove of attributeToRemove) {
10664
+ previousChildClone.removeAttribute(attrToRemove);
10665
+ }
10666
+ previousChildClone.setAttribute("data-ui-transition-clone", "");
10667
+ }
10668
+ overlay.appendChild(previousChildClone);
10669
+ }
10670
+ elementToImpact = overlay;
10671
+ cleanup = () => {
10672
+ if (!debugClones) {
10673
+ overlay.innerHTML = "";
10674
+ }
10675
+ };
10691
10676
  debug(
10692
10677
  "transition",
10693
10678
  `Cloned previous child for ${isPhaseTransition ? "phase" : "content"} transition:`,
10694
- getElementSignature(previousChild),
10679
+ getElementSignature(previousChildNodes),
10695
10680
  );
10696
- cleanup = () => oldChild.remove();
10697
10681
  } else {
10698
10682
  overlay.innerHTML = "";
10699
10683
  debug(
@@ -10709,16 +10693,15 @@ const initUITransition = (container) => {
10709
10693
  let newElement;
10710
10694
  if (isPhaseTransition) {
10711
10695
  // Phase transitions work on individual elements
10712
- oldElement = oldChild;
10713
- newElement = firstChild;
10696
+ oldElement = elementToImpact;
10697
+ newElement = slot;
10714
10698
  } else {
10715
10699
  // Content transitions work at container level and can outlive content phase changes
10716
- oldElement = oldChild ? overlay : null;
10717
- newElement = firstChild ? measureWrapper : null;
10700
+ oldElement = previousChildNodes.length ? elementToImpact : null;
10701
+ newElement = childNodes.length ? measureWrapper : null;
10718
10702
  }
10719
10703
 
10720
10704
  return {
10721
- oldChild,
10722
10705
  cleanup,
10723
10706
  oldElement,
10724
10707
  newElement,
@@ -10738,102 +10721,75 @@ const initUITransition = (container) => {
10738
10721
 
10739
10722
  try {
10740
10723
  isUpdating = true;
10741
- const firstChild = slot.children[0] || null;
10742
- const childUIName = firstChild?.getAttribute("data-ui-name");
10724
+ const childNodes = Array.from(slot.childNodes);
10743
10725
  if (localDebug.transition) {
10744
10726
  const updateLabel =
10745
- childUIName ||
10746
- (firstChild ? getElementSignature(firstChild) : "cleared/empty");
10727
+ childNodes.length === 0
10728
+ ? "cleared/empty"
10729
+ : childNodes.length === 1
10730
+ ? getElementSignature(childNodes[0])
10731
+ : getElementSignature(slot);
10747
10732
  console.group(`UI Update: ${updateLabel} (reason: ${reason})`);
10748
10733
  }
10749
10734
 
10750
- // Check for text nodes in the slot (not supported)
10751
- const hasTextNode = Array.from(slot.childNodes).some(
10752
- (node) => node.nodeType === Node.TEXT_NODE && node.textContent.trim(),
10753
- );
10754
- if (hasTextNode) {
10755
- console.warn(
10756
- "UI Transition: Text nodes in transition slots are not supported. Please wrap text content in an element.",
10757
- { slot, textContent: slot.textContent.trim() },
10758
- );
10759
- }
10760
-
10761
- // Check for multiple elements in the slot (not supported yet)
10762
- const hasMultipleElements = slot.children.length > 1;
10763
- if (hasMultipleElements) {
10764
- console.warn(
10765
- "UI Transition: Multiple elements in transition slots are not supported yet. Please use a single container element.",
10766
- { slot, elementCount: slot.children.length },
10767
- );
10768
- }
10735
+ // Determine transition scenarios early for early registration check
10736
+ // Prepare phase info early so logging can be unified (even for early return)
10737
+ wasContentPhase = isContentPhase;
10738
+ const hadChild = previousChildNodes.length > 0;
10739
+ const hasChild = childNodes.length > 0;
10769
10740
 
10770
10741
  // Prefer data-content-key on child, fallback to slot
10771
10742
  let currentContentKey = null;
10772
10743
  let slotContentKey = slot.getAttribute("data-content-key");
10773
- let childContentKey = firstChild?.getAttribute("data-content-key");
10744
+ let childContentKey;
10745
+
10746
+ if (childNodes.length === 0) {
10747
+ childContentKey = null;
10748
+ isContentPhase = true; // empty (no child) is treated as content phase
10749
+ } else {
10750
+ for (const childNode of childNodes) {
10751
+ if (childNode.nodeType === Node.TEXT_NODE) {
10752
+ } else if (childNode.hasAttribute("data-content-key")) {
10753
+ childContentKey = childNode.getAttribute("data-content-key");
10754
+ } else if (childNode.hasAttribute("data-content-phase")) {
10755
+ isContentPhase = true;
10756
+ }
10757
+ }
10758
+ }
10774
10759
  if (childContentKey && slotContentKey) {
10775
10760
  console.warn(
10776
- "Both data-content-key found on child and ui_transition_slot. Using child value.",
10777
- { childContentKey, slotContentKey },
10761
+ `Slot and slot child both have a [data-content-key]. Slot is ${slotContentKey} and child is ${childContentKey}, using the child.`,
10778
10762
  );
10779
10763
  }
10780
10764
  currentContentKey = childContentKey || slotContentKey || null;
10781
-
10782
- // Determine transition scenarios early for early registration check
10783
- const hadChild = previousChild !== null;
10784
- const hasChild = firstChild !== null;
10785
-
10786
- // Check for text nodes in previous state (reconstruct from previousChild)
10787
- const hadTextNode =
10788
- previousChild && previousChild.nodeType === Node.TEXT_NODE;
10789
-
10790
10765
  // Compute formatted content key states ONCE per mutation (requirement: max 2 calls)
10791
10766
  const previousContentKeyState = formatContentKeyState(
10792
10767
  lastContentKey,
10793
10768
  hadChild,
10794
- hadTextNode,
10795
10769
  );
10796
10770
  const currentContentKeyState = formatContentKeyState(
10797
10771
  currentContentKey,
10798
10772
  hasChild,
10799
- hasTextNode,
10800
10773
  );
10801
-
10802
10774
  // Track previous key before any potential early registration update
10803
10775
  const prevKeyBeforeRegistration = lastContentKey;
10804
-
10805
- // Prepare phase info early so logging can be unified (even for early return)
10806
- wasContentPhase = isContentPhase;
10807
- isContentPhase = firstChild
10808
- ? firstChild.hasAttribute("data-content-phase")
10809
- : true; // empty (no child) is treated as content phase
10810
-
10811
10776
  const previousIsContentPhase = !hadChild || wasContentPhase;
10812
10777
  const currentIsContentPhase = !hasChild || isContentPhase;
10813
10778
 
10814
- // Early conceptual registration path: empty slot, text nodes, or multiple elements (no visual transition)
10815
- const shouldGiveUpEarlyAndJustRegister =
10816
- (!hadChild && !hasChild && !hasTextNode) ||
10817
- hasTextNode ||
10818
- hasMultipleElements;
10779
+ // Early conceptual registration path: empty slot
10780
+ const shouldGiveUpEarlyAndJustRegister = !hadChild && !hasChild;
10819
10781
  let earlyAction = null;
10820
10782
  if (shouldGiveUpEarlyAndJustRegister) {
10821
- if (hasTextNode) {
10822
- earlyAction = "text_nodes_unsupported";
10823
- } else if (hasMultipleElements) {
10824
- earlyAction = "multiple_elements_unsupported";
10783
+ const prevKey = prevKeyBeforeRegistration;
10784
+ const keyChanged = prevKey !== currentContentKey;
10785
+ if (!keyChanged) {
10786
+ earlyAction = "unchanged";
10787
+ } else if (prevKey === null && currentContentKey !== null) {
10788
+ earlyAction = "registered";
10789
+ } else if (prevKey !== null && currentContentKey === null) {
10790
+ earlyAction = "cleared";
10825
10791
  } else {
10826
- const prevKey = prevKeyBeforeRegistration;
10827
- const keyChanged = prevKey !== currentContentKey;
10828
- if (!keyChanged) {
10829
- earlyAction = "unchanged";
10830
- } else if (prevKey === null && currentContentKey !== null) {
10831
- earlyAction = "registered";
10832
- } else if (prevKey !== null && currentContentKey === null) {
10833
- earlyAction = "cleared";
10834
- } else {
10835
- earlyAction = "changed";
10836
- }
10792
+ earlyAction = "changed";
10837
10793
  }
10838
10794
  // Will update lastContentKey after unified logging
10839
10795
  }
@@ -10884,7 +10840,7 @@ const initUITransition = (container) => {
10884
10840
 
10885
10841
  // Handle resize observation
10886
10842
  stopResizeObserver();
10887
- if (firstChild && !isContentPhase) {
10843
+ if (hasChild && !isContentPhase) {
10888
10844
  startResizeObserver();
10889
10845
  debug("size", "Observing child resize");
10890
10846
  }
@@ -10910,11 +10866,7 @@ const initUITransition = (container) => {
10910
10866
 
10911
10867
  // Content key change when either slot or child has data-content-key and it changed
10912
10868
  let shouldDoContentTransition = false;
10913
- if (
10914
- (slot.getAttribute("data-content-key") ||
10915
- firstChild?.getAttribute("data-content-key")) &&
10916
- lastContentKey !== null
10917
- ) {
10869
+ if (currentContentKey && lastContentKey !== null) {
10918
10870
  shouldDoContentTransition = currentContentKey !== lastContentKey;
10919
10871
  }
10920
10872
 
@@ -10998,7 +10950,7 @@ const initUITransition = (container) => {
10998
10950
  }
10999
10951
 
11000
10952
  // Register state and mark initial population done
11001
- previousChild = firstChild;
10953
+ previousChildNodes = childNodes;
11002
10954
  lastContentKey = currentContentKey;
11003
10955
  hasPopulatedOnce = true;
11004
10956
  if (localDebug.transition) {
@@ -11071,11 +11023,7 @@ const initUITransition = (container) => {
11071
11023
  shouldDoContentTransitionIncludingPopulation &&
11072
11024
  !preserveOnlyContentTransition
11073
11025
  ) {
11074
- const existingOldContents = contentOverlay.querySelectorAll(
11075
- "[data-ui-transition-old]",
11076
- );
11077
11026
  const animationProgress = activeContentTransition?.progress || 0;
11078
-
11079
11027
  if (animationProgress > 0) {
11080
11028
  debug(
11081
11029
  "transition",
@@ -11089,7 +11037,6 @@ const initUITransition = (container) => {
11089
11037
  const canContinueSmoothly =
11090
11038
  activeContentTransitionType === newTransitionType &&
11091
11039
  activeContentTransition;
11092
-
11093
11040
  if (canContinueSmoothly) {
11094
11041
  debug(
11095
11042
  "transition",
@@ -11110,11 +11057,8 @@ const initUITransition = (container) => {
11110
11057
  activeContentTransition.cancel();
11111
11058
  }
11112
11059
 
11113
- const needsOldChildClone =
11114
- (contentChange || becomesEmpty) &&
11115
- previousChild &&
11116
- !existingOldContents[0];
11117
-
11060
+ const needsOldChildNodesClone =
11061
+ (contentChange || becomesEmpty) && hadChild;
11118
11062
  const duration = parseInt(
11119
11063
  container.getAttribute("data-content-transition-duration") ||
11120
11064
  CONTENT_TRANSITION_DURATION,
@@ -11127,10 +11071,9 @@ const initUITransition = (container) => {
11127
11071
  setupTransition({
11128
11072
  isPhaseTransition: false,
11129
11073
  overlay: contentOverlay,
11130
- existingOldContents,
11131
- needsOldChildClone,
11132
- previousChild,
11133
- firstChild,
11074
+ needsOldChildNodesClone,
11075
+ previousChildNodes,
11076
+ childNodes,
11134
11077
  attributeToRemove: ["data-content-key"],
11135
11078
  });
11136
11079
 
@@ -11149,9 +11092,8 @@ const initUITransition = (container) => {
11149
11092
  }
11150
11093
  }
11151
11094
 
11152
- activeContentTransition = animateTransition(
11095
+ activeContentTransition = applyTransition(
11153
11096
  transitionController,
11154
- firstChild,
11155
11097
  setupContentTransition,
11156
11098
  {
11157
11099
  duration,
@@ -11193,12 +11135,7 @@ const initUITransition = (container) => {
11193
11135
  if (shouldDoPhaseTransition) {
11194
11136
  const phaseTransitionType =
11195
11137
  container.getAttribute("data-phase-transition") || PHASE_TRANSITION;
11196
-
11197
- const existingOldPhaseContents = phaseOverlay.querySelectorAll(
11198
- "[data-ui-transition-old]",
11199
- );
11200
11138
  const phaseAnimationProgress = activePhaseTransition?.progress || 0;
11201
-
11202
11139
  if (phaseAnimationProgress > 0) {
11203
11140
  debug(
11204
11141
  "transition",
@@ -11228,10 +11165,7 @@ const initUITransition = (container) => {
11228
11165
  }
11229
11166
 
11230
11167
  const needsOldPhaseClone =
11231
- (becomesEmpty || becomesPopulated || phaseChange) &&
11232
- previousChild &&
11233
- !existingOldPhaseContents[0];
11234
-
11168
+ (becomesEmpty || becomesPopulated || phaseChange) && hadChild;
11235
11169
  const phaseDuration = parseInt(
11236
11170
  container.getAttribute("data-phase-transition-duration") ||
11237
11171
  PHASE_TRANSITION_DURATION,
@@ -11241,10 +11175,9 @@ const initUITransition = (container) => {
11241
11175
  setupTransition({
11242
11176
  isPhaseTransition: true,
11243
11177
  overlay: phaseOverlay,
11244
- existingOldContents: existingOldPhaseContents,
11245
- needsOldChildClone: needsOldPhaseClone,
11246
- previousChild,
11247
- firstChild,
11178
+ needsOldChildNodesClone: needsOldPhaseClone,
11179
+ previousChildNodes,
11180
+ childNodes,
11248
11181
  attributeToRemove: ["data-content-key", "data-content-phase"],
11249
11182
  });
11250
11183
 
@@ -11264,9 +11197,8 @@ const initUITransition = (container) => {
11264
11197
  `Starting phase transition: ${fromPhase} → ${toPhase}`,
11265
11198
  );
11266
11199
 
11267
- activePhaseTransition = animateTransition(
11200
+ activePhaseTransition = applyTransition(
11268
11201
  transitionController,
11269
- firstChild,
11270
11202
  setupPhaseTransition,
11271
11203
  {
11272
11204
  duration: phaseDuration,
@@ -11292,7 +11224,7 @@ const initUITransition = (container) => {
11292
11224
  }
11293
11225
 
11294
11226
  // Store current child for next transition
11295
- previousChild = firstChild;
11227
+ previousChildNodes = childNodes;
11296
11228
  lastContentKey = currentContentKey;
11297
11229
  if (becomesPopulated) {
11298
11230
  hasPopulatedOnce = true;
@@ -11376,7 +11308,6 @@ const initUITransition = (container) => {
11376
11308
  characterData: false,
11377
11309
  });
11378
11310
 
11379
- // Return API
11380
11311
  return {
11381
11312
  slot,
11382
11313
 
@@ -11421,9 +11352,8 @@ const initUITransition = (container) => {
11421
11352
  };
11422
11353
  };
11423
11354
 
11424
- const animateTransition = (
11355
+ const applyTransition = (
11425
11356
  transitionController,
11426
- newChild,
11427
11357
  setupTransition,
11428
11358
  {
11429
11359
  type,
@@ -11445,7 +11375,7 @@ const animateTransition = (
11445
11375
  return null;
11446
11376
  }
11447
11377
 
11448
- const { cleanup, oldElement, newElement } = setupTransition();
11378
+ const { cleanup, oldElement, newElement, onTeardown } = setupTransition();
11449
11379
  // Use precomputed content key states (expected to be provided by caller)
11450
11380
  const fromContentKey = fromContentKeyState;
11451
11381
  const toContentKey = toContentKeyState;
@@ -11475,6 +11405,7 @@ const animateTransition = (
11475
11405
  if (transitions.length === 0) {
11476
11406
  debug("transition", "No transitions to animate, cleaning up immediately");
11477
11407
  cleanup();
11408
+ onTeardown?.();
11478
11409
  onComplete?.();
11479
11410
  return null;
11480
11411
  }
@@ -11483,6 +11414,7 @@ const animateTransition = (
11483
11414
  onFinish: () => {
11484
11415
  groupTransition.cancel();
11485
11416
  cleanup();
11417
+ onTeardown?.();
11486
11418
  onComplete?.();
11487
11419
  },
11488
11420
  });
@@ -11719,4 +11651,4 @@ const crossFade = {
11719
11651
  },
11720
11652
  };
11721
11653
 
11722
- export { EASING, activeElementSignal, addActiveElementEffect, addAttributeEffect, addWillChange, allowWheelThrough, appendStyles, canInterceptKeys, captureScrollState, createDragGestureController, createDragToMoveGestureController, createHeightTransition, createIterableWeakSet, createOpacityTransition, createPubSub, createStyleController, createTimelineTransition, createTransition, createTranslateXTransition, createValueEffect, createWidthTransition, cubicBezier, dragAfterThreshold, elementIsFocusable, elementIsVisibleForFocus, elementIsVisuallyVisible, findAfter, findAncestor, findBefore, findDescendant, findFocusable, getAvailableHeight, getAvailableWidth, getBorderSizes, getContrastRatio, getDefaultStyles, getDragCoordinates, getDropTargetInfo, getElementSignature, getFirstVisuallyVisibleAncestor, getFocusVisibilityInfo, getHeight, getInnerHeight, getInnerWidth, getMarginSizes, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getPaddingSizes, getPositionedParent, getPreferedColorScheme, getScrollContainer, getScrollContainerSet, getScrollRelativeRect, getSelfAndAncestorScrolls, getStyle, getVisuallyVisibleInfo, getWidth, initFlexDetailsSet, initFocusGroup, initPositionSticky, initUITransition, isScrollable, mergeStyles, normalizeStyles, parseCSSColor, pickLightOrDark, pickPositionRelativeTo, prefersDarkColors, prefersLightColors, preventFocusNav, preventFocusNavViaKeyboard, resolveCSSColor, resolveCSSSize, setAttribute, setAttributes, setStyles, startDragToResizeGesture, stickyAsRelativeCoords, stringifyCSSColor, trapFocusInside, trapScrollInside, useActiveElement, useAvailableHeight, useAvailableWidth, useMaxHeight, useMaxWidth, useResizeStatus, visibleRectEffect };
11654
+ export { EASING, activeElementSignal, addActiveElementEffect, addAttributeEffect, addWillChange, allowWheelThrough, appendStyles, canInterceptKeys, captureScrollState, createDragGestureController, createDragToMoveGestureController, createHeightTransition, createIterableWeakSet, createOpacityTransition, createPubSub, createStyleController, createTimelineTransition, createTransition, createTranslateXTransition, createValueEffect, createWidthTransition, cubicBezier, dragAfterThreshold, elementIsFocusable, elementIsVisibleForFocus, elementIsVisuallyVisible, findAfter, findAncestor, findBefore, findDescendant, findFocusable, getAvailableHeight, getAvailableWidth, getBorderSizes, getContrastRatio, getDefaultStyles, getDragCoordinates, getDropTargetInfo, getElementSignature, getFirstVisuallyVisibleAncestor, getFocusVisibilityInfo, getHeight, getInnerHeight, getInnerWidth, getMarginSizes, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getOpacity, getPaddingSizes, getPositionedParent, getPreferedColorScheme, getScrollContainer, getScrollContainerSet, getScrollRelativeRect, getSelfAndAncestorScrolls, getStyle, getTranslateX, getTranslateY, getVisuallyVisibleInfo, getWidth, initFlexDetailsSet, initFocusGroup, initPositionSticky, initUITransition, isScrollable, mergeStyles, normalizeStyles, parseCSSColor, pickLightOrDark, pickPositionRelativeTo, prefersDarkColors, prefersLightColors, preventFocusNav, preventFocusNavViaKeyboard, resolveCSSColor, resolveCSSSize, setAttribute, setAttributes, setStyles, startDragToResizeGesture, stickyAsRelativeCoords, stringifyCSSColor, trapFocusInside, trapScrollInside, useActiveElement, useAvailableHeight, useAvailableWidth, useMaxHeight, useMaxWidth, useResizeStatus, visibleRectEffect };