@wardic/solid 0.0.0-stage → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +26 -2
- package/THIRD_PARTY_NOTICES.md +145 -0
- package/dist/browser/animation-controls.js +150 -0
- package/dist/browser/animation-controls.js.map +1 -0
- package/dist/browser/animation-frame.js +29 -0
- package/dist/browser/animation-frame.js.map +1 -0
- package/dist/browser/appear.js +727 -0
- package/dist/browser/appear.js.map +1 -0
- package/dist/browser/arc.js +21 -0
- package/dist/browser/arc.js.map +1 -0
- package/dist/browser/bridge.js +69 -0
- package/dist/browser/bridge.js.map +1 -0
- package/dist/browser/complete.js +30 -0
- package/dist/browser/complete.js.map +1 -0
- package/dist/browser/config.js +2 -0
- package/dist/browser/config.js.map +1 -0
- package/dist/browser/create-animate.js +41 -0
- package/dist/browser/create-animate.js.map +1 -0
- package/dist/browser/create-ward.js +1001 -0
- package/dist/browser/create-ward.js.map +1 -0
- package/dist/browser/cycle-index.js +17 -0
- package/dist/browser/cycle-index.js.map +1 -0
- package/dist/browser/cycle.js +31 -0
- package/dist/browser/cycle.js.map +1 -0
- package/dist/browser/directive.js +80 -0
- package/dist/browser/directive.js.map +1 -0
- package/dist/browser/drag-constraints.js +76 -0
- package/dist/browser/drag-constraints.js.map +1 -0
- package/dist/browser/drag-controls.js +51 -0
- package/dist/browser/drag-controls.js.map +1 -0
- package/dist/browser/drag-samples.js +40 -0
- package/dist/browser/drag-samples.js.map +1 -0
- package/dist/browser/drag-sensor.js +35 -0
- package/dist/browser/drag-sensor.js.map +1 -0
- package/dist/browser/drag-track.js +817 -0
- package/dist/browser/drag-track.js.map +1 -0
- package/dist/browser/drag-transition.js +56 -0
- package/dist/browser/drag-transition.js.map +1 -0
- package/dist/browser/drag.js +44 -0
- package/dist/browser/drag.js.map +1 -0
- package/dist/browser/element-style.js +67 -0
- package/dist/browser/element-style.js.map +1 -0
- package/dist/browser/element.js +353 -0
- package/dist/browser/element.js.map +1 -0
- package/dist/browser/feature-section.js +17 -0
- package/dist/browser/feature-section.js.map +1 -0
- package/dist/browser/feature.js +261 -0
- package/dist/browser/feature.js.map +1 -0
- package/dist/browser/features/all.js +10 -0
- package/dist/browser/features/all.js.map +1 -0
- package/dist/browser/features/colors.js +33 -0
- package/dist/browser/features/colors.js.map +1 -0
- package/dist/browser/features/dom-animation.js +7 -0
- package/dist/browser/features/dom-animation.js.map +1 -0
- package/dist/browser/features/dom-max.js +4 -0
- package/dist/browser/features/dom-max.js.map +1 -0
- package/dist/browser/features/drag.js +28 -0
- package/dist/browser/features/drag.js.map +1 -0
- package/dist/browser/features/focus.js +18 -0
- package/dist/browser/features/focus.js.map +1 -0
- package/dist/browser/features/hover.js +18 -0
- package/dist/browser/features/hover.js.map +1 -0
- package/dist/browser/features/in-view.js +18 -0
- package/dist/browser/features/in-view.js.map +1 -0
- package/dist/browser/features/input.js +30 -0
- package/dist/browser/features/input.js.map +1 -0
- package/dist/browser/features/keys.js +19 -0
- package/dist/browser/features/keys.js.map +1 -0
- package/dist/browser/features/layout.js +33 -0
- package/dist/browser/features/layout.js.map +1 -0
- package/dist/browser/features/pan.js +18 -0
- package/dist/browser/features/pan.js.map +1 -0
- package/dist/browser/features/press.js +12 -0
- package/dist/browser/features/press.js.map +1 -0
- package/dist/browser/focus-sensor.js +23 -0
- package/dist/browser/focus-sensor.js.map +1 -0
- package/dist/browser/frame-time.js +40 -0
- package/dist/browser/frame-time.js.map +1 -0
- package/dist/browser/gesture-callbacks.js +172 -0
- package/dist/browser/gesture-callbacks.js.map +1 -0
- package/dist/browser/gesture-features.js +29 -0
- package/dist/browser/gesture-features.js.map +1 -0
- package/dist/browser/gesture-info.js +43 -0
- package/dist/browser/gesture-info.js.map +1 -0
- package/dist/browser/hover-sensor.js +29 -0
- package/dist/browser/hover-sensor.js.map +1 -0
- package/dist/browser/imperative.js +614 -0
- package/dist/browser/imperative.js.map +1 -0
- package/dist/browser/index.js +165 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/instant.js +51 -0
- package/dist/browser/instant.js.map +1 -0
- package/dist/browser/layout-group.js +27 -0
- package/dist/browser/layout-group.js.map +1 -0
- package/dist/browser/layout-member.js +362 -0
- package/dist/browser/layout-member.js.map +1 -0
- package/dist/browser/layout-projection.js +19 -0
- package/dist/browser/layout-projection.js.map +1 -0
- package/dist/browser/layout.js +91 -0
- package/dist/browser/layout.js.map +1 -0
- package/dist/browser/live-style.js +313 -0
- package/dist/browser/live-style.js.map +1 -0
- package/dist/browser/live-value.js +252 -0
- package/dist/browser/live-value.js.map +1 -0
- package/dist/browser/motion-props.js +172 -0
- package/dist/browser/motion-props.js.map +1 -0
- package/dist/browser/owner-scope.js +29 -0
- package/dist/browser/owner-scope.js.map +1 -0
- package/dist/browser/page-point.js +92 -0
- package/dist/browser/page-point.js.map +1 -0
- package/dist/browser/presence-controller.js +1324 -0
- package/dist/browser/presence-controller.js.map +1 -0
- package/dist/browser/presence-record.js +27 -0
- package/dist/browser/presence-record.js.map +1 -0
- package/dist/browser/presence.js +207 -0
- package/dist/browser/presence.js.map +1 -0
- package/dist/browser/press-sensor.js +30 -0
- package/dist/browser/press-sensor.js.map +1 -0
- package/dist/browser/press.js +24 -0
- package/dist/browser/press.js.map +1 -0
- package/dist/browser/provider.js +445 -0
- package/dist/browser/provider.js.map +1 -0
- package/dist/browser/reactivity.js +9 -0
- package/dist/browser/reactivity.js.map +1 -0
- package/dist/browser/reorder-input.js +46 -0
- package/dist/browser/reorder-input.js.map +1 -0
- package/dist/browser/reorder.js +543 -0
- package/dist/browser/reorder.js.map +1 -0
- package/dist/browser/retarget-legs.js +1019 -0
- package/dist/browser/retarget-legs.js.map +1 -0
- package/dist/browser/runtime.js +249 -0
- package/dist/browser/runtime.js.map +1 -0
- package/dist/browser/sensors.js +172 -0
- package/dist/browser/sensors.js.map +1 -0
- package/dist/browser/server-interpolators.js +20 -0
- package/dist/browser/server-interpolators.js.map +1 -0
- package/dist/browser/server.js +20 -0
- package/dist/browser/server.js.map +1 -0
- package/dist/browser/solid-reactivity.js +26 -0
- package/dist/browser/solid-reactivity.js.map +1 -0
- package/dist/browser/spine.js +2939 -0
- package/dist/browser/spine.js.map +1 -0
- package/dist/browser/stagger.js +13 -0
- package/dist/browser/stagger.js.map +1 -0
- package/dist/browser/unstable/v2/bridge.js +76 -0
- package/dist/browser/unstable/v2/bridge.js.map +1 -0
- package/dist/browser/unstable/v2/complete.js +29 -0
- package/dist/browser/unstable/v2/complete.js.map +1 -0
- package/dist/browser/unstable/v2/config-view.js +111 -0
- package/dist/browser/unstable/v2/config-view.js.map +1 -0
- package/dist/browser/unstable/v2/create-animate.js +102 -0
- package/dist/browser/unstable/v2/create-animate.js.map +1 -0
- package/dist/browser/unstable/v2/cycle.js +30 -0
- package/dist/browser/unstable/v2/cycle.js.map +1 -0
- package/dist/browser/unstable/v2/drag-sensor.js +34 -0
- package/dist/browser/unstable/v2/drag-sensor.js.map +1 -0
- package/dist/browser/unstable/v2/element.js +393 -0
- package/dist/browser/unstable/v2/element.js.map +1 -0
- package/dist/browser/unstable/v2/feature-section.js +27 -0
- package/dist/browser/unstable/v2/feature-section.js.map +1 -0
- package/dist/browser/unstable/v2/focus-sensor.js +23 -0
- package/dist/browser/unstable/v2/focus-sensor.js.map +1 -0
- package/dist/browser/unstable/v2/hover-sensor.js +28 -0
- package/dist/browser/unstable/v2/hover-sensor.js.map +1 -0
- package/dist/browser/unstable/v2/index.js +114 -0
- package/dist/browser/unstable/v2/index.js.map +1 -0
- package/dist/browser/unstable/v2/layout-projection.js +18 -0
- package/dist/browser/unstable/v2/layout-projection.js.map +1 -0
- package/dist/browser/unstable/v2/layout.js +71 -0
- package/dist/browser/unstable/v2/layout.js.map +1 -0
- package/dist/browser/unstable/v2/lifecycle.js +455 -0
- package/dist/browser/unstable/v2/lifecycle.js.map +1 -0
- package/dist/browser/unstable/v2/live-value.js +264 -0
- package/dist/browser/unstable/v2/live-value.js.map +1 -0
- package/dist/browser/unstable/v2/presence-handle.js +146 -0
- package/dist/browser/unstable/v2/presence-handle.js.map +1 -0
- package/dist/browser/unstable/v2/presence-hooks.js +142 -0
- package/dist/browser/unstable/v2/presence-hooks.js.map +1 -0
- package/dist/browser/unstable/v2/presence.js +124 -0
- package/dist/browser/unstable/v2/presence.js.map +1 -0
- package/dist/browser/unstable/v2/press-sensor.js +29 -0
- package/dist/browser/unstable/v2/press-sensor.js.map +1 -0
- package/dist/browser/unstable/v2/provider.js +457 -0
- package/dist/browser/unstable/v2/provider.js.map +1 -0
- package/dist/browser/unstable/v2/reorder.js +663 -0
- package/dist/browser/unstable/v2/reorder.js.map +1 -0
- package/dist/browser/unstable/v2/sensors.js +138 -0
- package/dist/browser/unstable/v2/sensors.js.map +1 -0
- package/dist/browser/unstable/v2/solid-reactivity.js +82 -0
- package/dist/browser/unstable/v2/solid-reactivity.js.map +1 -0
- package/dist/browser/unstable/v2/variant-node.js +395 -0
- package/dist/browser/unstable/v2/variant-node.js.map +1 -0
- package/dist/browser/unstable/v2/w.js +23 -0
- package/dist/browser/unstable/v2/w.js.map +1 -0
- package/dist/browser/unstable/v2/waiters.js +185 -0
- package/dist/browser/unstable/v2/waiters.js.map +1 -0
- package/dist/browser/unstable/v2/ward.js +1620 -0
- package/dist/browser/unstable/v2/ward.js.map +1 -0
- package/dist/browser/unstable/v2/wardic-config.js +40 -0
- package/dist/browser/unstable/v2/wardic-config.js.map +1 -0
- package/dist/browser/unstable/v2/wardic.js +16 -0
- package/dist/browser/unstable/v2/wardic.js.map +1 -0
- package/dist/browser/variant-node.js +308 -0
- package/dist/browser/variant-node.js.map +1 -0
- package/dist/browser/variant-target.js +224 -0
- package/dist/browser/variant-target.js.map +1 -0
- package/dist/browser/variant-tree.js +394 -0
- package/dist/browser/variant-tree.js.map +1 -0
- package/dist/browser/variants.js +43 -0
- package/dist/browser/variants.js.map +1 -0
- package/dist/browser/w.js +25 -0
- package/dist/browser/w.js.map +1 -0
- package/dist/browser/ward-keys.js +2 -0
- package/dist/browser/ward-keys.js.map +1 -0
- package/dist/browser/wardic-component.js +74 -0
- package/dist/browser/wardic-component.js.map +1 -0
- package/dist/browser/wardic-config-value.js +91 -0
- package/dist/browser/wardic-config-value.js.map +1 -0
- package/dist/browser/wardic-config.js +42 -0
- package/dist/browser/wardic-config.js.map +1 -0
- package/dist/browser/wardic.js +31 -0
- package/dist/browser/wardic.js.map +1 -0
- package/dist/server/animation-controls.js +150 -0
- package/dist/server/animation-controls.js.map +1 -0
- package/dist/server/animation-frame.js +29 -0
- package/dist/server/animation-frame.js.map +1 -0
- package/dist/server/appear.js +727 -0
- package/dist/server/appear.js.map +1 -0
- package/dist/server/arc.js +21 -0
- package/dist/server/arc.js.map +1 -0
- package/dist/server/bridge.js +69 -0
- package/dist/server/bridge.js.map +1 -0
- package/dist/server/complete.js +30 -0
- package/dist/server/complete.js.map +1 -0
- package/dist/server/config.js +2 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/create-animate.js +41 -0
- package/dist/server/create-animate.js.map +1 -0
- package/dist/server/create-ward.js +1001 -0
- package/dist/server/create-ward.js.map +1 -0
- package/dist/server/cycle-index.js +17 -0
- package/dist/server/cycle-index.js.map +1 -0
- package/dist/server/cycle.js +31 -0
- package/dist/server/cycle.js.map +1 -0
- package/dist/server/directive.js +80 -0
- package/dist/server/directive.js.map +1 -0
- package/dist/server/drag-constraints.js +76 -0
- package/dist/server/drag-constraints.js.map +1 -0
- package/dist/server/drag-controls.js +51 -0
- package/dist/server/drag-controls.js.map +1 -0
- package/dist/server/drag-samples.js +40 -0
- package/dist/server/drag-samples.js.map +1 -0
- package/dist/server/drag-sensor.js +35 -0
- package/dist/server/drag-sensor.js.map +1 -0
- package/dist/server/drag-track.js +817 -0
- package/dist/server/drag-track.js.map +1 -0
- package/dist/server/drag-transition.js +56 -0
- package/dist/server/drag-transition.js.map +1 -0
- package/dist/server/drag.js +44 -0
- package/dist/server/drag.js.map +1 -0
- package/dist/server/element-style.js +67 -0
- package/dist/server/element-style.js.map +1 -0
- package/dist/server/element.js +353 -0
- package/dist/server/element.js.map +1 -0
- package/dist/server/feature-section.js +17 -0
- package/dist/server/feature-section.js.map +1 -0
- package/dist/server/feature.js +261 -0
- package/dist/server/feature.js.map +1 -0
- package/dist/server/features/all.js +10 -0
- package/dist/server/features/all.js.map +1 -0
- package/dist/server/features/colors.js +33 -0
- package/dist/server/features/colors.js.map +1 -0
- package/dist/server/features/dom-animation.js +7 -0
- package/dist/server/features/dom-animation.js.map +1 -0
- package/dist/server/features/dom-max.js +4 -0
- package/dist/server/features/dom-max.js.map +1 -0
- package/dist/server/features/drag.js +28 -0
- package/dist/server/features/drag.js.map +1 -0
- package/dist/server/features/focus.js +18 -0
- package/dist/server/features/focus.js.map +1 -0
- package/dist/server/features/hover.js +18 -0
- package/dist/server/features/hover.js.map +1 -0
- package/dist/server/features/in-view.js +18 -0
- package/dist/server/features/in-view.js.map +1 -0
- package/dist/server/features/input.js +30 -0
- package/dist/server/features/input.js.map +1 -0
- package/dist/server/features/keys.js +19 -0
- package/dist/server/features/keys.js.map +1 -0
- package/dist/server/features/layout.js +33 -0
- package/dist/server/features/layout.js.map +1 -0
- package/dist/server/features/pan.js +18 -0
- package/dist/server/features/pan.js.map +1 -0
- package/dist/server/features/press.js +12 -0
- package/dist/server/features/press.js.map +1 -0
- package/dist/server/focus-sensor.js +23 -0
- package/dist/server/focus-sensor.js.map +1 -0
- package/dist/server/frame-time.js +40 -0
- package/dist/server/frame-time.js.map +1 -0
- package/dist/server/gesture-callbacks.js +172 -0
- package/dist/server/gesture-callbacks.js.map +1 -0
- package/dist/server/gesture-features.js +29 -0
- package/dist/server/gesture-features.js.map +1 -0
- package/dist/server/gesture-info.js +43 -0
- package/dist/server/gesture-info.js.map +1 -0
- package/dist/server/hover-sensor.js +29 -0
- package/dist/server/hover-sensor.js.map +1 -0
- package/dist/server/imperative.js +614 -0
- package/dist/server/imperative.js.map +1 -0
- package/dist/server/index.js +165 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/instant.js +51 -0
- package/dist/server/instant.js.map +1 -0
- package/dist/server/layout-group.js +27 -0
- package/dist/server/layout-group.js.map +1 -0
- package/dist/server/layout-member.js +362 -0
- package/dist/server/layout-member.js.map +1 -0
- package/dist/server/layout-projection.js +19 -0
- package/dist/server/layout-projection.js.map +1 -0
- package/dist/server/layout.js +90 -0
- package/dist/server/layout.js.map +1 -0
- package/dist/server/live-style.js +313 -0
- package/dist/server/live-style.js.map +1 -0
- package/dist/server/live-value.js +252 -0
- package/dist/server/live-value.js.map +1 -0
- package/dist/server/motion-props.js +172 -0
- package/dist/server/motion-props.js.map +1 -0
- package/dist/server/owner-scope.js +29 -0
- package/dist/server/owner-scope.js.map +1 -0
- package/dist/server/page-point.js +92 -0
- package/dist/server/page-point.js.map +1 -0
- package/dist/server/presence-controller.js +1324 -0
- package/dist/server/presence-controller.js.map +1 -0
- package/dist/server/presence-record.js +27 -0
- package/dist/server/presence-record.js.map +1 -0
- package/dist/server/presence.js +207 -0
- package/dist/server/presence.js.map +1 -0
- package/dist/server/press-sensor.js +30 -0
- package/dist/server/press-sensor.js.map +1 -0
- package/dist/server/press.js +24 -0
- package/dist/server/press.js.map +1 -0
- package/dist/server/provider.js +439 -0
- package/dist/server/provider.js.map +1 -0
- package/dist/server/reactivity.js +9 -0
- package/dist/server/reactivity.js.map +1 -0
- package/dist/server/reorder-input.js +46 -0
- package/dist/server/reorder-input.js.map +1 -0
- package/dist/server/reorder.js +543 -0
- package/dist/server/reorder.js.map +1 -0
- package/dist/server/retarget-legs.js +1019 -0
- package/dist/server/retarget-legs.js.map +1 -0
- package/dist/server/runtime.js +249 -0
- package/dist/server/runtime.js.map +1 -0
- package/dist/server/sensors.js +172 -0
- package/dist/server/sensors.js.map +1 -0
- package/dist/server/server-interpolators.js +20 -0
- package/dist/server/server-interpolators.js.map +1 -0
- package/dist/server/server.js +20 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/solid-reactivity.js +26 -0
- package/dist/server/solid-reactivity.js.map +1 -0
- package/dist/server/spine.js +2939 -0
- package/dist/server/spine.js.map +1 -0
- package/dist/server/stagger.js +13 -0
- package/dist/server/stagger.js.map +1 -0
- package/dist/server/unstable/v2/bridge.js +76 -0
- package/dist/server/unstable/v2/bridge.js.map +1 -0
- package/dist/server/unstable/v2/complete.js +29 -0
- package/dist/server/unstable/v2/complete.js.map +1 -0
- package/dist/server/unstable/v2/config-view.js +111 -0
- package/dist/server/unstable/v2/config-view.js.map +1 -0
- package/dist/server/unstable/v2/create-animate.js +102 -0
- package/dist/server/unstable/v2/create-animate.js.map +1 -0
- package/dist/server/unstable/v2/cycle.js +30 -0
- package/dist/server/unstable/v2/cycle.js.map +1 -0
- package/dist/server/unstable/v2/drag-sensor.js +34 -0
- package/dist/server/unstable/v2/drag-sensor.js.map +1 -0
- package/dist/server/unstable/v2/element.js +402 -0
- package/dist/server/unstable/v2/element.js.map +1 -0
- package/dist/server/unstable/v2/feature-section.js +27 -0
- package/dist/server/unstable/v2/feature-section.js.map +1 -0
- package/dist/server/unstable/v2/focus-sensor.js +23 -0
- package/dist/server/unstable/v2/focus-sensor.js.map +1 -0
- package/dist/server/unstable/v2/hover-sensor.js +28 -0
- package/dist/server/unstable/v2/hover-sensor.js.map +1 -0
- package/dist/server/unstable/v2/index.js +114 -0
- package/dist/server/unstable/v2/index.js.map +1 -0
- package/dist/server/unstable/v2/layout-projection.js +18 -0
- package/dist/server/unstable/v2/layout-projection.js.map +1 -0
- package/dist/server/unstable/v2/layout.js +88 -0
- package/dist/server/unstable/v2/layout.js.map +1 -0
- package/dist/server/unstable/v2/lifecycle.js +455 -0
- package/dist/server/unstable/v2/lifecycle.js.map +1 -0
- package/dist/server/unstable/v2/live-value.js +264 -0
- package/dist/server/unstable/v2/live-value.js.map +1 -0
- package/dist/server/unstable/v2/presence-handle.js +146 -0
- package/dist/server/unstable/v2/presence-handle.js.map +1 -0
- package/dist/server/unstable/v2/presence-hooks.js +142 -0
- package/dist/server/unstable/v2/presence-hooks.js.map +1 -0
- package/dist/server/unstable/v2/presence.js +142 -0
- package/dist/server/unstable/v2/presence.js.map +1 -0
- package/dist/server/unstable/v2/press-sensor.js +29 -0
- package/dist/server/unstable/v2/press-sensor.js.map +1 -0
- package/dist/server/unstable/v2/provider.js +475 -0
- package/dist/server/unstable/v2/provider.js.map +1 -0
- package/dist/server/unstable/v2/reorder.js +733 -0
- package/dist/server/unstable/v2/reorder.js.map +1 -0
- package/dist/server/unstable/v2/sensors.js +138 -0
- package/dist/server/unstable/v2/sensors.js.map +1 -0
- package/dist/server/unstable/v2/solid-reactivity.js +82 -0
- package/dist/server/unstable/v2/solid-reactivity.js.map +1 -0
- package/dist/server/unstable/v2/variant-node.js +395 -0
- package/dist/server/unstable/v2/variant-node.js.map +1 -0
- package/dist/server/unstable/v2/w.js +23 -0
- package/dist/server/unstable/v2/w.js.map +1 -0
- package/dist/server/unstable/v2/waiters.js +185 -0
- package/dist/server/unstable/v2/waiters.js.map +1 -0
- package/dist/server/unstable/v2/ward.js +1653 -0
- package/dist/server/unstable/v2/ward.js.map +1 -0
- package/dist/server/unstable/v2/wardic-config.js +49 -0
- package/dist/server/unstable/v2/wardic-config.js.map +1 -0
- package/dist/server/unstable/v2/wardic.js +16 -0
- package/dist/server/unstable/v2/wardic.js.map +1 -0
- package/dist/server/variant-node.js +308 -0
- package/dist/server/variant-node.js.map +1 -0
- package/dist/server/variant-target.js +224 -0
- package/dist/server/variant-target.js.map +1 -0
- package/dist/server/variant-tree.js +394 -0
- package/dist/server/variant-tree.js.map +1 -0
- package/dist/server/variants.js +43 -0
- package/dist/server/variants.js.map +1 -0
- package/dist/server/w.js +25 -0
- package/dist/server/w.js.map +1 -0
- package/dist/server/ward-keys.js +2 -0
- package/dist/server/ward-keys.js.map +1 -0
- package/dist/server/wardic-component.js +74 -0
- package/dist/server/wardic-component.js.map +1 -0
- package/dist/server/wardic-config-value.js +91 -0
- package/dist/server/wardic-config-value.js.map +1 -0
- package/dist/server/wardic-config.js +42 -0
- package/dist/server/wardic-config.js.map +1 -0
- package/dist/server/wardic.js +31 -0
- package/dist/server/wardic.js.map +1 -0
- package/dist/solid/animation-controls.d.ts +104 -0
- package/dist/solid/animation-controls.d.ts.map +1 -0
- package/dist/solid/animation-controls.js +129 -0
- package/dist/solid/animation-controls.js.map +1 -0
- package/dist/solid/animation-frame.d.ts +11 -0
- package/dist/solid/animation-frame.d.ts.map +1 -0
- package/dist/solid/animation-frame.js +31 -0
- package/dist/solid/animation-frame.js.map +1 -0
- package/dist/solid/appear.d.ts +205 -0
- package/dist/solid/appear.d.ts.map +1 -0
- package/dist/solid/appear.js +519 -0
- package/dist/solid/appear.js.map +1 -0
- package/dist/solid/arc.d.ts +25 -0
- package/dist/solid/arc.d.ts.map +1 -0
- package/dist/solid/arc.js +21 -0
- package/dist/solid/arc.js.map +1 -0
- package/dist/solid/bridge.d.ts +53 -0
- package/dist/solid/bridge.d.ts.map +1 -0
- package/dist/solid/bridge.js +66 -0
- package/dist/solid/bridge.js.map +1 -0
- package/dist/solid/complete.d.ts +31 -0
- package/dist/solid/complete.d.ts.map +1 -0
- package/dist/solid/complete.js +27 -0
- package/dist/solid/complete.js.map +1 -0
- package/dist/solid/config.d.ts +693 -0
- package/dist/solid/config.d.ts.map +1 -0
- package/dist/solid/config.js +2 -0
- package/dist/solid/config.js.map +1 -0
- package/dist/solid/create-animate.d.ts +17 -0
- package/dist/solid/create-animate.d.ts.map +1 -0
- package/dist/solid/create-animate.js +42 -0
- package/dist/solid/create-animate.js.map +1 -0
- package/dist/solid/create-ward.d.ts +278 -0
- package/dist/solid/create-ward.d.ts.map +1 -0
- package/dist/solid/create-ward.jsx +874 -0
- package/dist/solid/create-ward.jsx.map +1 -0
- package/dist/solid/cycle-index.d.ts +7 -0
- package/dist/solid/cycle-index.d.ts.map +1 -0
- package/dist/solid/cycle-index.js +17 -0
- package/dist/solid/cycle-index.js.map +1 -0
- package/dist/solid/cycle.d.ts +21 -0
- package/dist/solid/cycle.d.ts.map +1 -0
- package/dist/solid/cycle.js +31 -0
- package/dist/solid/cycle.js.map +1 -0
- package/dist/solid/directive.d.ts +21 -0
- package/dist/solid/directive.d.ts.map +1 -0
- package/dist/solid/directive.js +76 -0
- package/dist/solid/directive.js.map +1 -0
- package/dist/solid/drag-constraints.d.ts +46 -0
- package/dist/solid/drag-constraints.d.ts.map +1 -0
- package/dist/solid/drag-constraints.js +49 -0
- package/dist/solid/drag-constraints.js.map +1 -0
- package/dist/solid/drag-controls.d.ts +50 -0
- package/dist/solid/drag-controls.d.ts.map +1 -0
- package/dist/solid/drag-controls.js +51 -0
- package/dist/solid/drag-controls.js.map +1 -0
- package/dist/solid/drag-samples.d.ts +34 -0
- package/dist/solid/drag-samples.d.ts.map +1 -0
- package/dist/solid/drag-samples.js +28 -0
- package/dist/solid/drag-samples.js.map +1 -0
- package/dist/solid/drag-sensor.d.ts +23 -0
- package/dist/solid/drag-sensor.d.ts.map +1 -0
- package/dist/solid/drag-sensor.js +33 -0
- package/dist/solid/drag-sensor.js.map +1 -0
- package/dist/solid/drag-track.d.ts +227 -0
- package/dist/solid/drag-track.d.ts.map +1 -0
- package/dist/solid/drag-track.js +631 -0
- package/dist/solid/drag-track.js.map +1 -0
- package/dist/solid/drag-transition.d.ts +20 -0
- package/dist/solid/drag-transition.d.ts.map +1 -0
- package/dist/solid/drag-transition.js +31 -0
- package/dist/solid/drag-transition.js.map +1 -0
- package/dist/solid/drag.d.ts +23 -0
- package/dist/solid/drag.d.ts.map +1 -0
- package/dist/solid/drag.js +44 -0
- package/dist/solid/drag.js.map +1 -0
- package/dist/solid/element-style.d.ts +60 -0
- package/dist/solid/element-style.d.ts.map +1 -0
- package/dist/solid/element-style.js +50 -0
- package/dist/solid/element-style.js.map +1 -0
- package/dist/solid/element.d.ts +73 -0
- package/dist/solid/element.d.ts.map +1 -0
- package/dist/solid/element.jsx +326 -0
- package/dist/solid/element.jsx.map +1 -0
- package/dist/solid/feature-section.d.ts +18 -0
- package/dist/solid/feature-section.d.ts.map +1 -0
- package/dist/solid/feature-section.js +13 -0
- package/dist/solid/feature-section.js.map +1 -0
- package/dist/solid/feature.d.ts +114 -0
- package/dist/solid/feature.d.ts.map +1 -0
- package/dist/solid/feature.js +248 -0
- package/dist/solid/feature.js.map +1 -0
- package/dist/solid/features/all.d.ts +10 -0
- package/dist/solid/features/all.d.ts.map +1 -0
- package/dist/solid/features/all.js +10 -0
- package/dist/solid/features/all.js.map +1 -0
- package/dist/solid/features/colors.d.ts +12 -0
- package/dist/solid/features/colors.d.ts.map +1 -0
- package/dist/solid/features/colors.js +34 -0
- package/dist/solid/features/colors.js.map +1 -0
- package/dist/solid/features/dom-animation.d.ts +11 -0
- package/dist/solid/features/dom-animation.d.ts.map +1 -0
- package/dist/solid/features/dom-animation.js +7 -0
- package/dist/solid/features/dom-animation.js.map +1 -0
- package/dist/solid/features/dom-max.d.ts +10 -0
- package/dist/solid/features/dom-max.d.ts.map +1 -0
- package/dist/solid/features/dom-max.js +4 -0
- package/dist/solid/features/dom-max.js.map +1 -0
- package/dist/solid/features/drag.d.ts +5 -0
- package/dist/solid/features/drag.d.ts.map +1 -0
- package/dist/solid/features/drag.js +28 -0
- package/dist/solid/features/drag.js.map +1 -0
- package/dist/solid/features/focus.d.ts +5 -0
- package/dist/solid/features/focus.d.ts.map +1 -0
- package/dist/solid/features/focus.js +16 -0
- package/dist/solid/features/focus.js.map +1 -0
- package/dist/solid/features/hover.d.ts +5 -0
- package/dist/solid/features/hover.d.ts.map +1 -0
- package/dist/solid/features/hover.js +16 -0
- package/dist/solid/features/hover.js.map +1 -0
- package/dist/solid/features/in-view.d.ts +5 -0
- package/dist/solid/features/in-view.d.ts.map +1 -0
- package/dist/solid/features/in-view.js +16 -0
- package/dist/solid/features/in-view.js.map +1 -0
- package/dist/solid/features/input.d.ts +26 -0
- package/dist/solid/features/input.d.ts.map +1 -0
- package/dist/solid/features/input.js +31 -0
- package/dist/solid/features/input.js.map +1 -0
- package/dist/solid/features/keys.d.ts +70 -0
- package/dist/solid/features/keys.d.ts.map +1 -0
- package/dist/solid/features/keys.js +26 -0
- package/dist/solid/features/keys.js.map +1 -0
- package/dist/solid/features/layout.d.ts +32 -0
- package/dist/solid/features/layout.d.ts.map +1 -0
- package/dist/solid/features/layout.js +34 -0
- package/dist/solid/features/layout.js.map +1 -0
- package/dist/solid/features/pan.d.ts +5 -0
- package/dist/solid/features/pan.d.ts.map +1 -0
- package/dist/solid/features/pan.js +16 -0
- package/dist/solid/features/pan.js.map +1 -0
- package/dist/solid/features/press.d.ts +11 -0
- package/dist/solid/features/press.d.ts.map +1 -0
- package/dist/solid/features/press.js +10 -0
- package/dist/solid/features/press.js.map +1 -0
- package/dist/solid/focus-sensor.d.ts +19 -0
- package/dist/solid/focus-sensor.d.ts.map +1 -0
- package/dist/solid/focus-sensor.js +23 -0
- package/dist/solid/focus-sensor.js.map +1 -0
- package/dist/solid/frame-time.d.ts +21 -0
- package/dist/solid/frame-time.d.ts.map +1 -0
- package/dist/solid/frame-time.js +41 -0
- package/dist/solid/frame-time.js.map +1 -0
- package/dist/solid/gesture-callbacks.d.ts +53 -0
- package/dist/solid/gesture-callbacks.d.ts.map +1 -0
- package/dist/solid/gesture-callbacks.js +184 -0
- package/dist/solid/gesture-callbacks.js.map +1 -0
- package/dist/solid/gesture-features.d.ts +28 -0
- package/dist/solid/gesture-features.d.ts.map +1 -0
- package/dist/solid/gesture-features.js +29 -0
- package/dist/solid/gesture-features.js.map +1 -0
- package/dist/solid/gesture-info.d.ts +59 -0
- package/dist/solid/gesture-info.d.ts.map +1 -0
- package/dist/solid/gesture-info.js +23 -0
- package/dist/solid/gesture-info.js.map +1 -0
- package/dist/solid/hover-sensor.d.ts +19 -0
- package/dist/solid/hover-sensor.d.ts.map +1 -0
- package/dist/solid/hover-sensor.js +23 -0
- package/dist/solid/hover-sensor.js.map +1 -0
- package/dist/solid/imperative.d.ts +195 -0
- package/dist/solid/imperative.d.ts.map +1 -0
- package/dist/solid/imperative.js +536 -0
- package/dist/solid/imperative.js.map +1 -0
- package/dist/solid/index.d.ts +180 -0
- package/dist/solid/index.d.ts.map +1 -0
- package/dist/solid/index.js +165 -0
- package/dist/solid/index.js.map +1 -0
- package/dist/solid/instant.d.ts +44 -0
- package/dist/solid/instant.d.ts.map +1 -0
- package/dist/solid/instant.js +49 -0
- package/dist/solid/instant.js.map +1 -0
- package/dist/solid/layout-group.d.ts +14 -0
- package/dist/solid/layout-group.d.ts.map +1 -0
- package/dist/solid/layout-group.js +27 -0
- package/dist/solid/layout-group.js.map +1 -0
- package/dist/solid/layout-member.d.ts +117 -0
- package/dist/solid/layout-member.d.ts.map +1 -0
- package/dist/solid/layout-member.js +164 -0
- package/dist/solid/layout-member.js.map +1 -0
- package/dist/solid/layout-projection.d.ts +22 -0
- package/dist/solid/layout-projection.d.ts.map +1 -0
- package/dist/solid/layout-projection.js +19 -0
- package/dist/solid/layout-projection.js.map +1 -0
- package/dist/solid/layout.d.ts +76 -0
- package/dist/solid/layout.d.ts.map +1 -0
- package/dist/solid/layout.jsx +80 -0
- package/dist/solid/layout.jsx.map +1 -0
- package/dist/solid/live-style.d.ts +147 -0
- package/dist/solid/live-style.d.ts.map +1 -0
- package/dist/solid/live-style.js +304 -0
- package/dist/solid/live-style.js.map +1 -0
- package/dist/solid/live-value.d.ts +144 -0
- package/dist/solid/live-value.d.ts.map +1 -0
- package/dist/solid/live-value.js +223 -0
- package/dist/solid/live-value.js.map +1 -0
- package/dist/solid/motion-props.d.ts +75 -0
- package/dist/solid/motion-props.d.ts.map +1 -0
- package/dist/solid/motion-props.js +314 -0
- package/dist/solid/motion-props.js.map +1 -0
- package/dist/solid/owner-scope.d.ts +16 -0
- package/dist/solid/owner-scope.d.ts.map +1 -0
- package/dist/solid/owner-scope.js +31 -0
- package/dist/solid/owner-scope.js.map +1 -0
- package/dist/solid/page-point.d.ts +35 -0
- package/dist/solid/page-point.d.ts.map +1 -0
- package/dist/solid/page-point.js +87 -0
- package/dist/solid/page-point.js.map +1 -0
- package/dist/solid/presence-controller.d.ts +122 -0
- package/dist/solid/presence-controller.d.ts.map +1 -0
- package/dist/solid/presence-controller.js +1207 -0
- package/dist/solid/presence-controller.js.map +1 -0
- package/dist/solid/presence-record.d.ts +167 -0
- package/dist/solid/presence-record.d.ts.map +1 -0
- package/dist/solid/presence-record.js +26 -0
- package/dist/solid/presence-record.js.map +1 -0
- package/dist/solid/presence.d.ts +95 -0
- package/dist/solid/presence.d.ts.map +1 -0
- package/dist/solid/presence.jsx +195 -0
- package/dist/solid/presence.jsx.map +1 -0
- package/dist/solid/press-sensor.d.ts +20 -0
- package/dist/solid/press-sensor.d.ts.map +1 -0
- package/dist/solid/press-sensor.js +24 -0
- package/dist/solid/press-sensor.js.map +1 -0
- package/dist/solid/press.d.ts +24 -0
- package/dist/solid/press.d.ts.map +1 -0
- package/dist/solid/press.js +19 -0
- package/dist/solid/press.js.map +1 -0
- package/dist/solid/provider.d.ts +263 -0
- package/dist/solid/provider.d.ts.map +1 -0
- package/dist/solid/provider.jsx +411 -0
- package/dist/solid/provider.jsx.map +1 -0
- package/dist/solid/reactivity.d.ts +27 -0
- package/dist/solid/reactivity.d.ts.map +1 -0
- package/dist/solid/reactivity.js +9 -0
- package/dist/solid/reactivity.js.map +1 -0
- package/dist/solid/reorder-input.d.ts +22 -0
- package/dist/solid/reorder-input.d.ts.map +1 -0
- package/dist/solid/reorder-input.js +45 -0
- package/dist/solid/reorder-input.js.map +1 -0
- package/dist/solid/reorder.d.ts +241 -0
- package/dist/solid/reorder.d.ts.map +1 -0
- package/dist/solid/reorder.jsx +427 -0
- package/dist/solid/reorder.jsx.map +1 -0
- package/dist/solid/retarget-legs.d.ts +189 -0
- package/dist/solid/retarget-legs.d.ts.map +1 -0
- package/dist/solid/retarget-legs.js +825 -0
- package/dist/solid/retarget-legs.js.map +1 -0
- package/dist/solid/runtime.d.ts +179 -0
- package/dist/solid/runtime.d.ts.map +1 -0
- package/dist/solid/runtime.js +237 -0
- package/dist/solid/runtime.js.map +1 -0
- package/dist/solid/sensors.d.ts +95 -0
- package/dist/solid/sensors.d.ts.map +1 -0
- package/dist/solid/sensors.js +154 -0
- package/dist/solid/sensors.js.map +1 -0
- package/dist/solid/server-interpolators.d.ts +13 -0
- package/dist/solid/server-interpolators.d.ts.map +1 -0
- package/dist/solid/server-interpolators.js +20 -0
- package/dist/solid/server-interpolators.js.map +1 -0
- package/dist/solid/server.d.ts +9 -0
- package/dist/solid/server.d.ts.map +1 -0
- package/dist/solid/server.js +20 -0
- package/dist/solid/server.js.map +1 -0
- package/dist/solid/solid-reactivity.d.ts +3 -0
- package/dist/solid/solid-reactivity.d.ts.map +1 -0
- package/dist/solid/solid-reactivity.js +19 -0
- package/dist/solid/solid-reactivity.js.map +1 -0
- package/dist/solid/spine.d.ts +597 -0
- package/dist/solid/spine.d.ts.map +1 -0
- package/dist/solid/spine.js +2761 -0
- package/dist/solid/spine.js.map +1 -0
- package/dist/solid/stagger.d.ts +29 -0
- package/dist/solid/stagger.d.ts.map +1 -0
- package/dist/solid/stagger.js +13 -0
- package/dist/solid/stagger.js.map +1 -0
- package/dist/solid/unstable/v2/bridge.d.ts +33 -0
- package/dist/solid/unstable/v2/bridge.d.ts.map +1 -0
- package/dist/solid/unstable/v2/bridge.js +76 -0
- package/dist/solid/unstable/v2/bridge.js.map +1 -0
- package/dist/solid/unstable/v2/complete.d.ts +21 -0
- package/dist/solid/unstable/v2/complete.d.ts.map +1 -0
- package/dist/solid/unstable/v2/complete.js +27 -0
- package/dist/solid/unstable/v2/complete.js.map +1 -0
- package/dist/solid/unstable/v2/config-view.d.ts +49 -0
- package/dist/solid/unstable/v2/config-view.d.ts.map +1 -0
- package/dist/solid/unstable/v2/config-view.js +114 -0
- package/dist/solid/unstable/v2/config-view.js.map +1 -0
- package/dist/solid/unstable/v2/create-animate.d.ts +31 -0
- package/dist/solid/unstable/v2/create-animate.d.ts.map +1 -0
- package/dist/solid/unstable/v2/create-animate.js +102 -0
- package/dist/solid/unstable/v2/create-animate.js.map +1 -0
- package/dist/solid/unstable/v2/cycle.d.ts +20 -0
- package/dist/solid/unstable/v2/cycle.d.ts.map +1 -0
- package/dist/solid/unstable/v2/cycle.js +30 -0
- package/dist/solid/unstable/v2/cycle.js.map +1 -0
- package/dist/solid/unstable/v2/drag-sensor.d.ts +23 -0
- package/dist/solid/unstable/v2/drag-sensor.d.ts.map +1 -0
- package/dist/solid/unstable/v2/drag-sensor.js +32 -0
- package/dist/solid/unstable/v2/drag-sensor.js.map +1 -0
- package/dist/solid/unstable/v2/element.d.ts +178 -0
- package/dist/solid/unstable/v2/element.d.ts.map +1 -0
- package/dist/solid/unstable/v2/element.jsx +325 -0
- package/dist/solid/unstable/v2/element.jsx.map +1 -0
- package/dist/solid/unstable/v2/feature-section.d.ts +12 -0
- package/dist/solid/unstable/v2/feature-section.d.ts.map +1 -0
- package/dist/solid/unstable/v2/feature-section.js +23 -0
- package/dist/solid/unstable/v2/feature-section.js.map +1 -0
- package/dist/solid/unstable/v2/focus-sensor.d.ts +13 -0
- package/dist/solid/unstable/v2/focus-sensor.d.ts.map +1 -0
- package/dist/solid/unstable/v2/focus-sensor.js +23 -0
- package/dist/solid/unstable/v2/focus-sensor.js.map +1 -0
- package/dist/solid/unstable/v2/hover-sensor.d.ts +12 -0
- package/dist/solid/unstable/v2/hover-sensor.d.ts.map +1 -0
- package/dist/solid/unstable/v2/hover-sensor.js +22 -0
- package/dist/solid/unstable/v2/hover-sensor.js.map +1 -0
- package/dist/solid/unstable/v2/index.d.ts +131 -0
- package/dist/solid/unstable/v2/index.d.ts.map +1 -0
- package/dist/solid/unstable/v2/index.js +114 -0
- package/dist/solid/unstable/v2/index.js.map +1 -0
- package/dist/solid/unstable/v2/layout-projection.d.ts +21 -0
- package/dist/solid/unstable/v2/layout-projection.d.ts.map +1 -0
- package/dist/solid/unstable/v2/layout-projection.js +18 -0
- package/dist/solid/unstable/v2/layout-projection.js.map +1 -0
- package/dist/solid/unstable/v2/layout.d.ts +47 -0
- package/dist/solid/unstable/v2/layout.d.ts.map +1 -0
- package/dist/solid/unstable/v2/layout.jsx +62 -0
- package/dist/solid/unstable/v2/layout.jsx.map +1 -0
- package/dist/solid/unstable/v2/lifecycle.d.ts +267 -0
- package/dist/solid/unstable/v2/lifecycle.d.ts.map +1 -0
- package/dist/solid/unstable/v2/lifecycle.js +457 -0
- package/dist/solid/unstable/v2/lifecycle.js.map +1 -0
- package/dist/solid/unstable/v2/live-value.d.ts +146 -0
- package/dist/solid/unstable/v2/live-value.d.ts.map +1 -0
- package/dist/solid/unstable/v2/live-value.js +235 -0
- package/dist/solid/unstable/v2/live-value.js.map +1 -0
- package/dist/solid/unstable/v2/presence-handle.d.ts +55 -0
- package/dist/solid/unstable/v2/presence-handle.d.ts.map +1 -0
- package/dist/solid/unstable/v2/presence-handle.js +119 -0
- package/dist/solid/unstable/v2/presence-handle.js.map +1 -0
- package/dist/solid/unstable/v2/presence-hooks.d.ts +51 -0
- package/dist/solid/unstable/v2/presence-hooks.d.ts.map +1 -0
- package/dist/solid/unstable/v2/presence-hooks.js +115 -0
- package/dist/solid/unstable/v2/presence-hooks.js.map +1 -0
- package/dist/solid/unstable/v2/presence.d.ts +89 -0
- package/dist/solid/unstable/v2/presence.d.ts.map +1 -0
- package/dist/solid/unstable/v2/presence.jsx +107 -0
- package/dist/solid/unstable/v2/presence.jsx.map +1 -0
- package/dist/solid/unstable/v2/press-sensor.d.ts +13 -0
- package/dist/solid/unstable/v2/press-sensor.d.ts.map +1 -0
- package/dist/solid/unstable/v2/press-sensor.js +23 -0
- package/dist/solid/unstable/v2/press-sensor.js.map +1 -0
- package/dist/solid/unstable/v2/provider.d.ts +239 -0
- package/dist/solid/unstable/v2/provider.d.ts.map +1 -0
- package/dist/solid/unstable/v2/provider.jsx +423 -0
- package/dist/solid/unstable/v2/provider.jsx.map +1 -0
- package/dist/solid/unstable/v2/reorder.d.ts +292 -0
- package/dist/solid/unstable/v2/reorder.d.ts.map +1 -0
- package/dist/solid/unstable/v2/reorder.jsx +525 -0
- package/dist/solid/unstable/v2/reorder.jsx.map +1 -0
- package/dist/solid/unstable/v2/sensors.d.ts +91 -0
- package/dist/solid/unstable/v2/sensors.d.ts.map +1 -0
- package/dist/solid/unstable/v2/sensors.js +124 -0
- package/dist/solid/unstable/v2/sensors.js.map +1 -0
- package/dist/solid/unstable/v2/solid-reactivity.d.ts +61 -0
- package/dist/solid/unstable/v2/solid-reactivity.d.ts.map +1 -0
- package/dist/solid/unstable/v2/solid-reactivity.js +62 -0
- package/dist/solid/unstable/v2/solid-reactivity.js.map +1 -0
- package/dist/solid/unstable/v2/variant-node.d.ts +51 -0
- package/dist/solid/unstable/v2/variant-node.d.ts.map +1 -0
- package/dist/solid/unstable/v2/variant-node.js +336 -0
- package/dist/solid/unstable/v2/variant-node.js.map +1 -0
- package/dist/solid/unstable/v2/w.d.ts +42 -0
- package/dist/solid/unstable/v2/w.d.ts.map +1 -0
- package/dist/solid/unstable/v2/w.jsx +22 -0
- package/dist/solid/unstable/v2/w.jsx.map +1 -0
- package/dist/solid/unstable/v2/waiters.d.ts +72 -0
- package/dist/solid/unstable/v2/waiters.d.ts.map +1 -0
- package/dist/solid/unstable/v2/waiters.js +175 -0
- package/dist/solid/unstable/v2/waiters.js.map +1 -0
- package/dist/solid/unstable/v2/ward.d.ts +393 -0
- package/dist/solid/unstable/v2/ward.d.ts.map +1 -0
- package/dist/solid/unstable/v2/ward.jsx +1475 -0
- package/dist/solid/unstable/v2/ward.jsx.map +1 -0
- package/dist/solid/unstable/v2/wardic-config.d.ts +68 -0
- package/dist/solid/unstable/v2/wardic-config.d.ts.map +1 -0
- package/dist/solid/unstable/v2/wardic-config.jsx +28 -0
- package/dist/solid/unstable/v2/wardic-config.jsx.map +1 -0
- package/dist/solid/unstable/v2/wardic.d.ts +28 -0
- package/dist/solid/unstable/v2/wardic.d.ts.map +1 -0
- package/dist/solid/unstable/v2/wardic.jsx +16 -0
- package/dist/solid/unstable/v2/wardic.jsx.map +1 -0
- package/dist/solid/variant-node.d.ts +32 -0
- package/dist/solid/variant-node.d.ts.map +1 -0
- package/dist/solid/variant-node.js +257 -0
- package/dist/solid/variant-node.js.map +1 -0
- package/dist/solid/variant-target.d.ts +102 -0
- package/dist/solid/variant-target.d.ts.map +1 -0
- package/dist/solid/variant-target.js +180 -0
- package/dist/solid/variant-target.js.map +1 -0
- package/dist/solid/variant-tree.d.ts +349 -0
- package/dist/solid/variant-tree.d.ts.map +1 -0
- package/dist/solid/variant-tree.js +358 -0
- package/dist/solid/variant-tree.js.map +1 -0
- package/dist/solid/variants.d.ts +21 -0
- package/dist/solid/variants.d.ts.map +1 -0
- package/dist/solid/variants.js +43 -0
- package/dist/solid/variants.js.map +1 -0
- package/dist/solid/w.d.ts +42 -0
- package/dist/solid/w.d.ts.map +1 -0
- package/dist/solid/w.jsx +23 -0
- package/dist/solid/w.jsx.map +1 -0
- package/dist/solid/ward-keys.d.ts +236 -0
- package/dist/solid/ward-keys.d.ts.map +1 -0
- package/dist/solid/ward-keys.js +2 -0
- package/dist/solid/ward-keys.js.map +1 -0
- package/dist/solid/wardic-component.d.ts +50 -0
- package/dist/solid/wardic-component.d.ts.map +1 -0
- package/dist/solid/wardic-component.js +74 -0
- package/dist/solid/wardic-component.js.map +1 -0
- package/dist/solid/wardic-config-value.d.ts +87 -0
- package/dist/solid/wardic-config-value.d.ts.map +1 -0
- package/dist/solid/wardic-config-value.js +106 -0
- package/dist/solid/wardic-config-value.js.map +1 -0
- package/dist/solid/wardic-config.d.ts +69 -0
- package/dist/solid/wardic-config.d.ts.map +1 -0
- package/dist/solid/wardic-config.jsx +30 -0
- package/dist/solid/wardic-config.jsx.map +1 -0
- package/dist/solid/wardic.d.ts +45 -0
- package/dist/solid/wardic.d.ts.map +1 -0
- package/dist/solid/wardic.jsx +31 -0
- package/dist/solid/wardic.jsx.map +1 -0
- package/package.json +98 -4
- package/src/animation-controls.ts +204 -0
- package/src/animation-frame.ts +32 -0
- package/src/appear.ts +804 -0
- package/src/arc.ts +34 -0
- package/src/bridge.ts +98 -0
- package/src/complete.ts +45 -0
- package/src/config.ts +805 -0
- package/src/create-animate.ts +41 -0
- package/src/create-ward.tsx +1271 -0
- package/src/cycle-index.ts +18 -0
- package/src/cycle.ts +34 -0
- package/src/directive.ts +87 -0
- package/src/drag-constraints.ts +103 -0
- package/src/drag-controls.ts +94 -0
- package/src/drag-samples.ts +54 -0
- package/src/drag-sensor.ts +46 -0
- package/src/drag-track.ts +937 -0
- package/src/drag-transition.ts +43 -0
- package/src/drag.ts +58 -0
- package/src/element-style.ts +112 -0
- package/src/element.tsx +400 -0
- package/src/feature-section.ts +33 -0
- package/src/feature.ts +342 -0
- package/src/features/all.ts +18 -0
- package/src/features/colors.ts +36 -0
- package/src/features/dom-animation.ts +15 -0
- package/src/features/dom-max.ts +11 -0
- package/src/features/drag.ts +30 -0
- package/src/features/focus.ts +17 -0
- package/src/features/hover.ts +17 -0
- package/src/features/in-view.ts +17 -0
- package/src/features/input.ts +42 -0
- package/src/features/keys.ts +89 -0
- package/src/features/layout.ts +54 -0
- package/src/features/pan.ts +17 -0
- package/src/features/press.ts +17 -0
- package/src/focus-sensor.ts +32 -0
- package/src/frame-time.ts +45 -0
- package/src/gesture-callbacks.ts +212 -0
- package/src/gesture-features.ts +35 -0
- package/src/gesture-info.ts +81 -0
- package/src/hover-sensor.ts +32 -0
- package/src/imperative.ts +782 -0
- package/src/index.ts +334 -0
- package/src/instant.ts +90 -0
- package/src/layout-group.ts +32 -0
- package/src/layout-member.ts +300 -0
- package/src/layout-projection.ts +28 -0
- package/src/layout.tsx +127 -0
- package/src/live-style.ts +449 -0
- package/src/live-value.ts +378 -0
- package/src/motion-props.ts +325 -0
- package/src/owner-scope.ts +31 -0
- package/src/page-point.ts +98 -0
- package/src/presence-controller.ts +1483 -0
- package/src/presence-record.ts +189 -0
- package/src/presence.tsx +269 -0
- package/src/press-sensor.ts +33 -0
- package/src/press.ts +40 -0
- package/src/provider.tsx +526 -0
- package/src/reactivity.ts +29 -0
- package/src/reorder-input.ts +53 -0
- package/src/reorder.tsx +703 -0
- package/src/retarget-legs.ts +1048 -0
- package/src/runtime.ts +388 -0
- package/src/sensors.ts +189 -0
- package/src/server-interpolators.ts +33 -0
- package/src/server.ts +21 -0
- package/src/solid-reactivity.ts +21 -0
- package/src/spine.ts +3385 -0
- package/src/stagger.ts +31 -0
- package/src/unstable/v2/bridge.ts +79 -0
- package/src/unstable/v2/complete.ts +47 -0
- package/src/unstable/v2/config-view.ts +156 -0
- package/src/unstable/v2/create-animate.ts +123 -0
- package/src/unstable/v2/cycle.ts +33 -0
- package/src/unstable/v2/drag-sensor.ts +44 -0
- package/src/unstable/v2/element.tsx +478 -0
- package/src/unstable/v2/feature-section.ts +32 -0
- package/src/unstable/v2/focus-sensor.ts +31 -0
- package/src/unstable/v2/hover-sensor.ts +30 -0
- package/src/unstable/v2/index.ts +270 -0
- package/src/unstable/v2/layout-projection.ts +27 -0
- package/src/unstable/v2/layout.tsx +89 -0
- package/src/unstable/v2/lifecycle.ts +612 -0
- package/src/unstable/v2/live-value.ts +414 -0
- package/src/unstable/v2/presence-handle.ts +159 -0
- package/src/unstable/v2/presence-hooks.ts +157 -0
- package/src/unstable/v2/presence.tsx +174 -0
- package/src/unstable/v2/press-sensor.ts +31 -0
- package/src/unstable/v2/provider.tsx +524 -0
- package/src/unstable/v2/reorder.tsx +880 -0
- package/src/unstable/v2/sensors.ts +169 -0
- package/src/unstable/v2/solid-reactivity.ts +69 -0
- package/src/unstable/v2/variant-node.ts +446 -0
- package/src/unstable/v2/w.tsx +49 -0
- package/src/unstable/v2/waiters.ts +212 -0
- package/src/unstable/v2/ward.tsx +2068 -0
- package/src/unstable/v2/wardic-config.tsx +84 -0
- package/src/unstable/v2/wardic.tsx +41 -0
- package/src/variant-node.ts +368 -0
- package/src/variant-target.ts +234 -0
- package/src/variant-tree.ts +638 -0
- package/src/variants.ts +47 -0
- package/src/w.tsx +59 -0
- package/src/ward-keys.ts +343 -0
- package/src/wardic-component.ts +96 -0
- package/src/wardic-config-value.ts +150 -0
- package/src/wardic-config.tsx +78 -0
- package/src/wardic.tsx +59 -0
|
@@ -0,0 +1,1483 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<AnimatePresence>`'s work (ADR-0007), Solid-free (#209): each leaving child's retained node, its
|
|
3
|
+
* parent-driven exit, and the twins it hands back (ADR-0010 *Amendment (#181)*). Each binding's
|
|
4
|
+
* `AnimatePresence` resolves its children with its own Solid and tells
|
|
5
|
+
* {@link PresenceController.present} which are present after each change; see the Solid 1 binding's
|
|
6
|
+
* `presence.tsx` for the doctrine.
|
|
7
|
+
*
|
|
8
|
+
* Many children (#277, ADR-0048): a child is its DOM node, so one that leaves is the node that left
|
|
9
|
+
* the resolved children, each exiting on its own, in its place. A child that comes back mid-exit is
|
|
10
|
+
* a new node: under the leaver's `key` it takes over from where the leaver is (#286); without one it
|
|
11
|
+
* enters beside the leaver while the leaver finishes.
|
|
12
|
+
*
|
|
13
|
+
* `mode="wait"` (#277, ADR-0048): while a child exits, one entering is held off the page, its wards
|
|
14
|
+
* not started, and goes on it once the last leaver is gone. Its framework has built it already, so
|
|
15
|
+
* its own code has run; what waits is its place on the page and everything Wardic does with it.
|
|
16
|
+
*
|
|
17
|
+
* `mode="popLayout"` (#277, ADR-0048): a leaver is measured before the change and popped out of the
|
|
18
|
+
* flow where it was (`position: absolute`, its size kept), so the children after it take their
|
|
19
|
+
* places at once. Whatever the mode, the projection is told when a leaver is popped or removed, so
|
|
20
|
+
* a `layout` sibling animates into the space, as Motion's presence re-renders its children then.
|
|
21
|
+
*
|
|
22
|
+
* @module
|
|
23
|
+
*/
|
|
24
|
+
import type * as Box from "@wardic/core/Box"
|
|
25
|
+
import type * as DefaultTransition from "@wardic/core/DefaultTransition"
|
|
26
|
+
import type * as Frame from "@wardic/core/Frame"
|
|
27
|
+
import type * as FrameLoop from "@wardic/core/FrameLoop"
|
|
28
|
+
import * as InterpolatorRegistry from "@wardic/core/InterpolatorRegistry"
|
|
29
|
+
import type * as ReducedMotion from "@wardic/core/ReducedMotion"
|
|
30
|
+
import * as Renderer from "@wardic/core/Renderer"
|
|
31
|
+
import * as Values from "@wardic/core/Values"
|
|
32
|
+
import * as Machine from "@wardic/core/Machine"
|
|
33
|
+
import * as Microtask from "@wardic/core/Microtask"
|
|
34
|
+
import * as Velocity from "@wardic/core/Velocity"
|
|
35
|
+
import type * as ProjectionSystem from "@wardic/dom/ProjectionSystem"
|
|
36
|
+
import * as DomRenderer from "@wardic/dom/DomRenderer"
|
|
37
|
+
import * as MeasuredPair from "@wardic/dom/MeasuredPair"
|
|
38
|
+
import * as Report from "@wardic/dom/Report"
|
|
39
|
+
import * as Variables from "@wardic/dom/Variables"
|
|
40
|
+
import * as Arr from "effect/Array"
|
|
41
|
+
import * as Bool from "effect/Boolean"
|
|
42
|
+
import * as Cause from "effect/Cause"
|
|
43
|
+
import * as Effect from "effect/Effect"
|
|
44
|
+
import type * as Fiber from "effect/Fiber"
|
|
45
|
+
import { constFalse, constUndefined, constVoid, identity } from "effect/Function"
|
|
46
|
+
import * as Option from "effect/Option"
|
|
47
|
+
import * as Predicate from "effect/Predicate"
|
|
48
|
+
import * as Rec from "effect/Record"
|
|
49
|
+
import * as UndefinedOr from "effect/UndefinedOr"
|
|
50
|
+
import type { WardicTransition, WardicVariantLabels } from "./config.ts"
|
|
51
|
+
import type { ExitGroup, PresenceContextValue, PresenceExit, PresenceRecord, PresenceSeed, PresenceTree, PresenceWatch } from "./presence-record.ts"
|
|
52
|
+
import { delayedBy, hasManyStops, keyframesFrom, type Leg, legsOf, type MeasuredPairs, type StopsByKey, velocitiesOf } from "./retarget-legs.ts"
|
|
53
|
+
import type { WardicRuntime, WardicServices } from "./runtime.ts"
|
|
54
|
+
import { childDelayOf, staggerOf } from "./variant-tree.ts"
|
|
55
|
+
|
|
56
|
+
/** Whether a value-map has any keys (an empty exit means "remove immediately"). */
|
|
57
|
+
const isEmpty = (values: Values.Values): boolean => Rec.isEmptyRecord(values)
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* An element's values as they're drawn, without its Transform template (#443): it rides in its
|
|
61
|
+
* presence record to draw its exit through, and isn't a value a child back under its key takes over.
|
|
62
|
+
*/
|
|
63
|
+
const valuesDrawn = (values: Values.Values): Values.Values => Rec.remove(values, DomRenderer.TEMPLATE_KEY)
|
|
64
|
+
|
|
65
|
+
/** An exit's spring: the defaults, one object, so core decodes it once (#66). */
|
|
66
|
+
|
|
67
|
+
/** A record's place in the variant tree (#290): left out, a lone element's. */
|
|
68
|
+
const LONE: PresenceTree = { joins: false, provides: false, twin: false }
|
|
69
|
+
|
|
70
|
+
/** A record's place in the variant tree, {@link LONE} without one. */
|
|
71
|
+
const treeOf = (rec: PresenceRecord): PresenceTree => UndefinedOr.match(rec.tree, { onUndefined: () => LONE, onDefined: identity })
|
|
72
|
+
|
|
73
|
+
/** No elements: a leaving child with none inside it exiting. */
|
|
74
|
+
const NO_PARTS: ReadonlyArray<HTMLElement> = []
|
|
75
|
+
|
|
76
|
+
/** No records: nothing registered inside a leaving child. */
|
|
77
|
+
const NO_RECORDS: ReadonlyArray<PresenceRecord | undefined> = []
|
|
78
|
+
|
|
79
|
+
/** No record of its own: a plain leaving child (#392). */
|
|
80
|
+
const NO_OWN: ReadonlyArray<PresenceRecord> = []
|
|
81
|
+
|
|
82
|
+
/** A leaving element's exit, and its Variant children's, resolved at the leave (#290). */
|
|
83
|
+
interface ExitNode {
|
|
84
|
+
readonly rec: PresenceRecord
|
|
85
|
+
readonly exit: PresenceExit
|
|
86
|
+
readonly kids: ReadonlyArray<ExitNode>
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Whether an exit node, or one under it, has anything to animate. */
|
|
90
|
+
const busy = (node: ExitNode): boolean => Bool.or(Bool.not(isEmpty(node.exit.values)), Arr.some(node.kids, busy))
|
|
91
|
+
|
|
92
|
+
/** No velocities: an element with no spine to read them from (#464: one with a spine starts its exit from its own). */
|
|
93
|
+
const NO_VELOCITIES: Readonly<Record<string, number>> = {}
|
|
94
|
+
|
|
95
|
+
/** Where an element is drawn (#286): its values, and each numeric key's velocity. */
|
|
96
|
+
type Drawn = PresenceSeed
|
|
97
|
+
|
|
98
|
+
/** No boxes: a leaver none of whose elements was on the page. */
|
|
99
|
+
const NO_BOXES: ReadonlyMap<Element, Box.Box> = new Map()
|
|
100
|
+
|
|
101
|
+
/** A Wardic element made under a presence (#286): its `key`, if it has one, and whether it's a twin. */
|
|
102
|
+
interface Made {
|
|
103
|
+
readonly key: string | number | undefined
|
|
104
|
+
readonly twin: boolean
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Whether two lists of elements have the same shape (#286): as many, each pair the same tag. */
|
|
108
|
+
const sameShape = (a: ReadonlyArray<Element>, b: ReadonlyArray<Element>): boolean =>
|
|
109
|
+
Bool.and(a.length === b.length, Arr.every(Arr.zip(a, b), ([x, y]) => x.tagName === y.tagName))
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Each numeric key's velocity from a step's frame (#286): its change since the step before, over
|
|
113
|
+
* the step's `dt` (seconds), and 0 once the frame settles. A key's first step sets nothing.
|
|
114
|
+
*/
|
|
115
|
+
const measure = (velocities: Record<string, number>, last: Record<string, number>, frame: Frame.Frame<Values.Values>, dt: number): void => {
|
|
116
|
+
Arr.forEach(Rec.keys(frame.value), (key) => {
|
|
117
|
+
const now = frame.value[key]
|
|
118
|
+
if (Predicate.isString(now)) return
|
|
119
|
+
const before = last[key]
|
|
120
|
+
last[key] = now
|
|
121
|
+
if (frame.done) {
|
|
122
|
+
velocities[key] = 0
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
if (Predicate.isUndefined(before)) return
|
|
126
|
+
if (dt <= 0) return
|
|
127
|
+
velocities[key] = Velocity.between(before, now, dt)
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** A blend's machine, its numeric keys' velocities measured each step (#286): a tween's frames carry none. */
|
|
132
|
+
const measuredInto =
|
|
133
|
+
(velocities: Record<string, number>) =>
|
|
134
|
+
(machine: Machine.Machine<Frame.Frame<Values.Values>>): Machine.Machine<Frame.Frame<Values.Values>> =>
|
|
135
|
+
Machine.make({
|
|
136
|
+
settles: machine.settles,
|
|
137
|
+
span: machine.span,
|
|
138
|
+
start: () => {
|
|
139
|
+
const step = machine.start()
|
|
140
|
+
const last: Record<string, number> = {}
|
|
141
|
+
return (dt) => {
|
|
142
|
+
const frame = step(dt)
|
|
143
|
+
measure(velocities, last, frame, Math.min(dt, Machine.MAX_DT))
|
|
144
|
+
return frame
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* One leg of an exit (#277), as the spine runs a Retarget's, committing onto the retained `el`. Each
|
|
151
|
+
* key's velocity goes into `velocities` (#286): a spring's from its frames, a blend's measured, a
|
|
152
|
+
* snap's 0, so a child back under its key starts with it.
|
|
153
|
+
*/
|
|
154
|
+
const exitRunOf = (
|
|
155
|
+
leg: Leg,
|
|
156
|
+
el: HTMLElement,
|
|
157
|
+
commitFrame: FrameLoop.Sink<Frame.Frame<Values.Values>>,
|
|
158
|
+
velocities: Record<string, number>,
|
|
159
|
+
): Effect.Effect<unknown, never, WardicServices> => {
|
|
160
|
+
if (leg._tag === "Blend") {
|
|
161
|
+
return Effect.suspend(leg.machine).pipe(
|
|
162
|
+
InterpolatorRegistry.withKeyRules([Variables.values(el)]),
|
|
163
|
+
Effect.map(measuredInto(velocities)),
|
|
164
|
+
Effect.flatMap(Machine.run(commitFrame)),
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
if (leg._tag === "Follow") {
|
|
168
|
+
const key = leg.key
|
|
169
|
+
return Effect.suspend(() =>
|
|
170
|
+
leg.machine().pipe(
|
|
171
|
+
Machine.run((frame) => {
|
|
172
|
+
velocities[key] = UndefinedOr.match(frame.velocity, { onUndefined: () => 0, onDefined: identity })
|
|
173
|
+
return commitFrame({ ...frame, value: { [key]: frame.value } })
|
|
174
|
+
}),
|
|
175
|
+
))
|
|
176
|
+
}
|
|
177
|
+
if (leg._tag === "Numbers") {
|
|
178
|
+
return Effect.suspend(() =>
|
|
179
|
+
leg.machine().pipe(
|
|
180
|
+
Machine.run((frame) => {
|
|
181
|
+
Object.assign(velocities, frame.velocity)
|
|
182
|
+
return commitFrame(frame)
|
|
183
|
+
}),
|
|
184
|
+
))
|
|
185
|
+
}
|
|
186
|
+
Arr.forEach(leg.keys, (key) => {
|
|
187
|
+
velocities[key] = 0
|
|
188
|
+
})
|
|
189
|
+
return Effect.suspend(() => leg.machine().pipe(Machine.run(commitFrame)))
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** How far in each name's keys of an exit start (#297): seconds, by name; `undefined` for an exit that isn't a list's. */
|
|
193
|
+
type DelayOf = (name: string | undefined) => number
|
|
194
|
+
|
|
195
|
+
/** At once, every name. */
|
|
196
|
+
const NO_DELAY: DelayOf = () => 0
|
|
197
|
+
|
|
198
|
+
/** An element's exit made ready to run (#297's PR 2): its node, where it starts, what each frame commits, and its velocities. */
|
|
199
|
+
interface PreparedExit {
|
|
200
|
+
readonly el: HTMLElement
|
|
201
|
+
readonly from: Values.Values
|
|
202
|
+
/** Its Keyframes of more than two stops (#429), `from` at their first. */
|
|
203
|
+
readonly stops: StopsByKey | undefined
|
|
204
|
+
readonly commitFrame: FrameLoop.Sink<Frame.Frame<Values.Values>>
|
|
205
|
+
readonly velocities: Record<string, number>
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* An exit's Measured pairs (#430): each key whose start and target differ in type, asked of the
|
|
210
|
+
* end-of-task batch, but a key with Keyframes of more than two stops (`stops`, #460). `undefined` with
|
|
211
|
+
* none, nearly every exit.
|
|
212
|
+
*/
|
|
213
|
+
const exitMeasuredOf = (element: HTMLElement, from: Values.Values, to: Values.Values, stops: StopsByKey | undefined): MeasuredPairs | undefined => {
|
|
214
|
+
const pairs = Rec.filter(to, (target, key) => Bool.and(Bool.and(Object.hasOwn(from, key), Bool.not(hasManyStops(stops, key))), keepsMeasured(key, from[key], target)))
|
|
215
|
+
if (Rec.isEmptyRecord(pairs)) return undefined
|
|
216
|
+
return MeasuredPair.measure(element, Rec.map(pairs, (target, key) => ({ from: UndefinedOr.getOrThrow(from[key]), to: target })), from)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Whether a start and a target make a Measured pair (#430). */
|
|
220
|
+
const keepsMeasured = (key: string, start: number | string | undefined, target: number | string): boolean => {
|
|
221
|
+
if (Predicate.isUndefined(start)) return false
|
|
222
|
+
return MeasuredPair.needs(key, start, target)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** An exit's name when it's one name, for its delay; `undefined` for a list or a values map. */
|
|
226
|
+
const singleNameOf = (name: WardicVariantLabels | undefined): string | undefined => {
|
|
227
|
+
if (Predicate.isString(name)) return name
|
|
228
|
+
return undefined
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** The transition a name of an exit orchestrates its Variant children's keys on (#297): its group's, else the exit's. */
|
|
232
|
+
const transitionOfName = (exit: PresenceExit, name: string | undefined): WardicTransition | undefined => {
|
|
233
|
+
const groups = exit.groups
|
|
234
|
+
if (Bool.or(Predicate.isUndefined(groups), Predicate.isUndefined(name))) return exit.transition
|
|
235
|
+
return Option.match(Arr.findFirst(groups as ReadonlyArray<ExitGroup>, (group) => group.name === name), {
|
|
236
|
+
onNone: () => exit.transition,
|
|
237
|
+
onSome: (group) => group.transition,
|
|
238
|
+
})
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** Whether a resolved child is an element. Only called on the client, where `HTMLElement` exists. */
|
|
242
|
+
const isHTMLElement = (node: unknown): node is HTMLElement => node instanceof HTMLElement
|
|
243
|
+
|
|
244
|
+
/** The elements of what a binding's `children()` resolved: one node, a flat array, or none. */
|
|
245
|
+
const elementsOf = (resolved: unknown): ReadonlyArray<HTMLElement> => Arr.filter(Arr.ensure(resolved), isHTMLElement)
|
|
246
|
+
|
|
247
|
+
/** A child present at the last change: its element, and where it was then, to put it back as it leaves. */
|
|
248
|
+
interface Placed {
|
|
249
|
+
readonly el: HTMLElement
|
|
250
|
+
readonly parent: ParentNode | undefined
|
|
251
|
+
readonly next: ChildNode | undefined
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Where `el` is now. */
|
|
255
|
+
const placedOf = (el: HTMLElement): Placed => ({
|
|
256
|
+
el,
|
|
257
|
+
parent: Option.getOrUndefined(Option.fromNullOr(el.parentNode)),
|
|
258
|
+
next: Option.getOrUndefined(Option.fromNullOr(el.nextSibling)),
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Where `popLayout` pins a leaver (#277, ADR-0048), measured before the change as Motion's `PopChild`
|
|
263
|
+
* measures it: its size (`getComputedStyle`, so its own `box-sizing` reads it back), and its margin
|
|
264
|
+
* box's offset from its containing block's padding edge on the two edges its anchors name (#442):
|
|
265
|
+
* the top or the bottom, and its inline start or end (Motion's `anchorX` `"left"` or `"right"`, which
|
|
266
|
+
* a right-to-left one flips). The offsets are whole pixels, the DOM's `offsetTop`.
|
|
267
|
+
*/
|
|
268
|
+
interface PopBox {
|
|
269
|
+
readonly width: number
|
|
270
|
+
readonly height: number
|
|
271
|
+
readonly y: "top" | "bottom"
|
|
272
|
+
readonly yAt: number
|
|
273
|
+
readonly x: "left" | "right"
|
|
274
|
+
readonly xAt: number
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Where a presence's `popLayout` pins a leaver (#442, Motion's `anchorX` and `anchorY`): its default, the inline start and the top. */
|
|
278
|
+
export interface PopAnchors {
|
|
279
|
+
readonly x: "left" | "right"
|
|
280
|
+
readonly y: "top" | "bottom"
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/** The size of the padding box `el`'s offsets are from: its offset parent's, or the viewport's. */
|
|
284
|
+
const containerOf = (el: HTMLElement): { readonly width: number; readonly height: number } => {
|
|
285
|
+
const parent = el.offsetParent
|
|
286
|
+
if (isHTMLElement(parent) && parent !== document.body) return { width: parent.clientWidth, height: parent.clientHeight }
|
|
287
|
+
return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight }
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** A px length of a computed style, `0` for none. */
|
|
291
|
+
const pxOf = (value: string): number => {
|
|
292
|
+
const px = Number.parseFloat(value)
|
|
293
|
+
if (Number.isNaN(px)) return 0
|
|
294
|
+
return px
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Where `el` is now, to pop it (#277): `undefined` for one with no size of its own (an inline element,
|
|
299
|
+
* or an empty one) or not on the page, which isn't popped, as Motion's.
|
|
300
|
+
*/
|
|
301
|
+
const popBoxOf = (el: HTMLElement, anchors: PopAnchors): PopBox | undefined => {
|
|
302
|
+
const style = getComputedStyle(el)
|
|
303
|
+
const width = Number.parseFloat(style.width)
|
|
304
|
+
const height = Number.parseFloat(style.height)
|
|
305
|
+
if (Bool.not(Bool.and(width > 0, height > 0))) return undefined
|
|
306
|
+
const container = containerOf(el)
|
|
307
|
+
// Positioned by its margin box, as its offsets are its border box's. Each edge's distance from the
|
|
308
|
+
// container's same edge; `anchorX` names the inline start (`"left"`) or end, which a right-to-left
|
|
309
|
+
// one flips, as Motion's.
|
|
310
|
+
const x = Bool.match((anchors.x === "right") !== (style.direction === "rtl"), { onTrue: (): PopBox["x"] => "right", onFalse: (): PopBox["x"] => "left" })
|
|
311
|
+
const xAt = Bool.match(x === "right", {
|
|
312
|
+
onTrue: () => container.width - el.offsetLeft - el.offsetWidth - pxOf(style.marginRight),
|
|
313
|
+
onFalse: () => el.offsetLeft - pxOf(style.marginLeft),
|
|
314
|
+
})
|
|
315
|
+
const yAt = Bool.match(anchors.y === "bottom", {
|
|
316
|
+
onTrue: () => container.height - el.offsetTop - el.offsetHeight - pxOf(style.marginBottom),
|
|
317
|
+
onFalse: () => el.offsetTop - pxOf(style.marginTop),
|
|
318
|
+
})
|
|
319
|
+
return { width, height, y: anchors.y, yAt, x, xAt }
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/** Pin a leaver where `box` measured it, out of the flow, over any style of its own. */
|
|
323
|
+
const pin = (el: HTMLElement, box: PopBox): void => {
|
|
324
|
+
const style = el.style
|
|
325
|
+
style.setProperty("position", "absolute", "important")
|
|
326
|
+
style.setProperty("width", `${box.width}px`, "important")
|
|
327
|
+
style.setProperty("height", `${box.height}px`, "important")
|
|
328
|
+
style.setProperty(box.y, `${box.yAt}px`, "important")
|
|
329
|
+
style.setProperty(box.x, `${box.xAt}px`, "important")
|
|
330
|
+
// Out of the flow over what took its place, it takes none of its clicks (#486). Not Motion's: its
|
|
331
|
+
// popped child still takes input. It's never unpinned: a child that comes back is a new element.
|
|
332
|
+
style.setProperty("pointer-events", "none", "important")
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* A popped leaver moved by `by` in the page from where `box` pinned it (ADR-0048 *Amendment (#480)*):
|
|
337
|
+
* each pinned edge by its axis's move, a right or bottom one against it.
|
|
338
|
+
*/
|
|
339
|
+
const movePin = (el: HTMLElement, box: PopBox, by: { readonly x: number; readonly y: number }): void => {
|
|
340
|
+
const style = el.style
|
|
341
|
+
style.setProperty(box.y, `${box.yAt + EDGE_BY[box.y] * by.y}px`, "important")
|
|
342
|
+
style.setProperty(box.x, `${box.xAt + EDGE_BY[box.x] * by.x}px`, "important")
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/** Which way a move along the page moves a pinned edge's offset: with a left or top one, against a right or bottom one. */
|
|
346
|
+
const EDGE_BY = { left: 1, right: -1, top: 1, bottom: -1 } as const
|
|
347
|
+
|
|
348
|
+
/** The element its first child sits in, if it's one (#277's PR 5c). */
|
|
349
|
+
const parentElementOf = (placed: ReadonlyArray<Placed>): Element | undefined =>
|
|
350
|
+
UndefinedOr.map(UndefinedOr.map(placed[0], (first) => first.parent), (parent) => {
|
|
351
|
+
if (parent instanceof Element) return parent
|
|
352
|
+
return undefined
|
|
353
|
+
})
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* The children in Motion's order for a change (#486, its `AnimatePresence`, #3746 there): `now`, with
|
|
357
|
+
* each of `before`, the children as they were, leavers still exiting among them, that isn't in `now`
|
|
358
|
+
* put back right after the staying child it followed, after the others put back there; first, when it
|
|
359
|
+
* followed none.
|
|
360
|
+
*/
|
|
361
|
+
const orderOf = (before: ReadonlyArray<HTMLElement>, now: ReadonlyArray<HTMLElement>): ReadonlyArray<HTMLElement> => {
|
|
362
|
+
const at = new Map(Arr.map(now, (el, i) => [el, i] as const))
|
|
363
|
+
return Arr.reduce(before, { order: [...now], next: 0, back: 0 }, (acc, el) =>
|
|
364
|
+
UndefinedOr.match(at.get(el), {
|
|
365
|
+
onUndefined: () => {
|
|
366
|
+
acc.order.splice(acc.next, 0, el)
|
|
367
|
+
return { order: acc.order, next: acc.next + 1, back: acc.back + 1 }
|
|
368
|
+
},
|
|
369
|
+
onDefined: (i) => ({ order: acc.order, next: i + acc.back + 1, back: acc.back }),
|
|
370
|
+
})).order
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Where the leaver at `i` in `order` goes back (#486): right after the nearest child before it that's on
|
|
375
|
+
* the page, or before the nearest one after it; where it was, with neither.
|
|
376
|
+
*/
|
|
377
|
+
const backPlaceOf = (placed: Placed, order: ReadonlyArray<HTMLElement>, i: number): Placed => {
|
|
378
|
+
const before = Arr.findLast(Arr.take(order, i), (el) => el.isConnected)
|
|
379
|
+
const after = Arr.findFirst(Arr.drop(order, i + 1), (el) => el.isConnected)
|
|
380
|
+
return Option.match(before, {
|
|
381
|
+
onSome: (el) => ({ el: placed.el, parent: Option.getOrUndefined(Option.fromNullOr(el.parentNode)), next: Option.getOrUndefined(Option.fromNullOr(el.nextSibling)) }),
|
|
382
|
+
onNone: () =>
|
|
383
|
+
Option.match(after, {
|
|
384
|
+
onSome: (el) => ({ el: placed.el, parent: Option.getOrUndefined(Option.fromNullOr(el.parentNode)), next: el }),
|
|
385
|
+
onNone: () => placed,
|
|
386
|
+
}),
|
|
387
|
+
})
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/** Put a retained node back into the parent it left: before its old next sibling while that's still there, else at the end. */
|
|
391
|
+
const reinsert = (el: Node, parent: ParentNode, next: ChildNode | undefined): void => {
|
|
392
|
+
if (Predicate.isNotUndefined(next) && next.parentNode === parent) {
|
|
393
|
+
parent.insertBefore(el, next)
|
|
394
|
+
return
|
|
395
|
+
}
|
|
396
|
+
parent.appendChild(el)
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* How a presence's children enter while others exit, Motion's `mode`: `"sync"`, at
|
|
401
|
+
* once, beside the leavers; `"wait"`, once every leaver is gone; `"popLayout"`, at once, each leaver
|
|
402
|
+
* popped out of the flow where it was.
|
|
403
|
+
*/
|
|
404
|
+
export type PresenceMode = "sync" | "wait" | "popLayout"
|
|
405
|
+
|
|
406
|
+
/** What a presence reads from its provider and its props. */
|
|
407
|
+
export interface PresenceOptions {
|
|
408
|
+
readonly runtime: WardicRuntime
|
|
409
|
+
/** The Environment's Renderer (ADR-0003), read once by the provider (#618, M1): what a retained node's values commit through. */
|
|
410
|
+
readonly renderer: Renderer.Renderer["Service"]
|
|
411
|
+
/** The provider's projection system once its `layout` Feature is built (#511), read at each use. */
|
|
412
|
+
readonly projection: () => ProjectionSystem.Shape | undefined
|
|
413
|
+
/** Whether reduced motion applies now (ADR-0029), read at each exit. */
|
|
414
|
+
readonly reducedMotion: () => boolean
|
|
415
|
+
readonly positionalKeys: ReducedMotion.PositionalKeys["Service"]
|
|
416
|
+
/** What an exit's key with no transition of its own runs on (ADR-0051). */
|
|
417
|
+
readonly defaultTransition: DefaultTransition.DefaultTransition["Service"]
|
|
418
|
+
/** The presence's `initial` prop: `false` starts the child present at its first render at its `animate` (#134). */
|
|
419
|
+
readonly initial: () => boolean | undefined
|
|
420
|
+
/** What its binding hears of its exits (#257); left out, nothing is told. */
|
|
421
|
+
readonly events?: PresenceEvents | undefined
|
|
422
|
+
/**
|
|
423
|
+
* Its `custom` prop (#277, Motion's), read as a child leaves: what the child's dynamic exit resolves
|
|
424
|
+
* with, over the child's own. Left out, the child's own.
|
|
425
|
+
*/
|
|
426
|
+
readonly custom?: (() => unknown) | undefined
|
|
427
|
+
/** Its `mode` prop (#277), read at each change: left out, or `undefined`, `"sync"`. */
|
|
428
|
+
readonly mode?: (() => PresenceMode | undefined) | undefined
|
|
429
|
+
/**
|
|
430
|
+
* Its `anchorX` and `anchorY` props (#442, Motion's), read as `popLayout` measures a leaver: the
|
|
431
|
+
* edges it's pinned by. Left out, or `undefined`, the inline start (`"left"`) and the top.
|
|
432
|
+
*/
|
|
433
|
+
readonly anchorX?: (() => PopAnchors["x"] | undefined) | undefined
|
|
434
|
+
readonly anchorY?: (() => PopAnchors["y"] | undefined) | undefined
|
|
435
|
+
/**
|
|
436
|
+
* Its `presenceAffectsLayout` prop (#442, Motion's), read at each change: whether the projection is
|
|
437
|
+
* told when its children move (a child entering, a leaver popped or removed), so a `layout` sibling
|
|
438
|
+
* animates into or out of the space. Left out, or `undefined`, `true`.
|
|
439
|
+
*/
|
|
440
|
+
readonly presenceAffectsLayout?: (() => boolean | undefined) | undefined
|
|
441
|
+
/**
|
|
442
|
+
* The children `mode="wait"` held may go on the page now: the binding renders its children again,
|
|
443
|
+
* through {@link PresenceController.shown}. Left out, a held child stays held.
|
|
444
|
+
*/
|
|
445
|
+
readonly release?: (() => void) | undefined
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* A presence's exits, told to its binding (#257, ADR-0046): Solid 1's `onExitComplete`, Solid 2's
|
|
450
|
+
* presence handle. A child that leaves exits; a child with no record (not a Wardic element) leaves at
|
|
451
|
+
* once, its exit starting and ending together, as Motion's does.
|
|
452
|
+
*/
|
|
453
|
+
export interface PresenceEvents {
|
|
454
|
+
/** A child left, and its exit starts. */
|
|
455
|
+
readonly exitStart: () => void
|
|
456
|
+
/** Whether any child is exiting, at each change: on at an exit's start, off once none is left. */
|
|
457
|
+
readonly exiting: (exiting: boolean) => void
|
|
458
|
+
/**
|
|
459
|
+
* Every exiting child has animated out and been removed, the last by completing (Motion's
|
|
460
|
+
* `onExitComplete`). Not when the last ended by an interrupt: a re-entry, or the teardown.
|
|
461
|
+
*/
|
|
462
|
+
readonly exitComplete: () => void
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/** A presence's work, driven by its binding. */
|
|
466
|
+
export interface PresenceController {
|
|
467
|
+
/** What its children's wards register with. */
|
|
468
|
+
readonly context: PresenceContextValue
|
|
469
|
+
/** The presence has mounted: a child that enters from now on animates in (#134). */
|
|
470
|
+
readonly mounted: () => void
|
|
471
|
+
/**
|
|
472
|
+
* The children present now, after a change (a node, a flat array of them, or none): each that left
|
|
473
|
+
* is retained in its place and exits. Called after the binding's framework has applied the change.
|
|
474
|
+
*/
|
|
475
|
+
readonly present: (current: unknown) => void
|
|
476
|
+
/**
|
|
477
|
+
* What goes on the page of what the children resolved to (#277): all of it, but under `mode="wait"`,
|
|
478
|
+
* while a child exits or is leaving in this change, each child entering is held off it until the
|
|
479
|
+
* last leaver is gone ({@link PresenceOptions.release}). Called where the binding renders, before
|
|
480
|
+
* the change is applied; {@link present} is then told what it showed.
|
|
481
|
+
*/
|
|
482
|
+
readonly shown: (resolved: unknown) => unknown
|
|
483
|
+
/**
|
|
484
|
+
* `propagate` (#277's PR 5c): every child present leaves, as if the change took them all, and
|
|
485
|
+
* `done` is called once none is left (at once with none).
|
|
486
|
+
*/
|
|
487
|
+
readonly leaveAll: (done: () => void) => void
|
|
488
|
+
/**
|
|
489
|
+
* Where its children are: the parent node of the last it had (#277's PR 5c), what a parent
|
|
490
|
+
* presence finds it inside. `undefined` before it had one.
|
|
491
|
+
*/
|
|
492
|
+
readonly anchor: () => Element | undefined
|
|
493
|
+
/** The presence's teardown: every exit in flight interrupted, every retained node removed. */
|
|
494
|
+
readonly teardown: () => void
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Solid 1's {@link PresenceEvents} (#257): only Motion's `onExitComplete`, read when it's called. One
|
|
499
|
+
* that throws is reported (`wardic.presence: onExitComplete failed`), and the presence goes on.
|
|
500
|
+
*/
|
|
501
|
+
export const exitCompleteEvents = (runtime: WardicRuntime, onExitComplete: () => (() => void) | undefined): PresenceEvents => ({
|
|
502
|
+
exitStart: constVoid,
|
|
503
|
+
exiting: constVoid,
|
|
504
|
+
exitComplete: () => {
|
|
505
|
+
const callback = onExitComplete()
|
|
506
|
+
if (Predicate.isUndefined(callback)) return
|
|
507
|
+
try {
|
|
508
|
+
callback()
|
|
509
|
+
} catch (defect) {
|
|
510
|
+
runtime.runFork(Report.failure("wardic.presence: onExitComplete failed", Cause.die(defect)))
|
|
511
|
+
}
|
|
512
|
+
},
|
|
513
|
+
})
|
|
514
|
+
|
|
515
|
+
/** What a presence asks of the projection system. */
|
|
516
|
+
type PresenceProjection = Pick<
|
|
517
|
+
ProjectionSystem.Shape,
|
|
518
|
+
"notify" | "handleLeave" | "handBackWithin" | "keepLeaving" | "awaitsTwin" | "keepSeen" | "registerValues" | "rootBoxOf" | "dropLeaver"
|
|
519
|
+
>
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* The projection system as a presence asks it (#511): the provider's once its `layout` Feature is
|
|
523
|
+
* built, read at each call, as a presence brings no Feature; until then, what one with no layout node
|
|
524
|
+
* answers: no twin to cross-fade or hand back, no leaving node to keep, nothing to tell. A popped
|
|
525
|
+
* leaver isn't kept where it was seen across a scroll then (ADR-0048 *Amendment (#480)*): the
|
|
526
|
+
* projection's frame does that.
|
|
527
|
+
*/
|
|
528
|
+
const presenceProjectionOf = (projection: () => ProjectionSystem.Shape | undefined): PresenceProjection => {
|
|
529
|
+
const call = <A>(use: (system: ProjectionSystem.Shape) => A, none: () => A): A => UndefinedOr.match(projection(), { onUndefined: none, onDefined: use })
|
|
530
|
+
return {
|
|
531
|
+
notify: () => call((system) => system.notify(), constVoid),
|
|
532
|
+
handleLeave: (el, onDone) => call((system) => system.handleLeave(el, onDone), constFalse),
|
|
533
|
+
handBackWithin: (el, onDone) => call((system) => system.handBackWithin(el, onDone), Option.none),
|
|
534
|
+
keepLeaving: (el, taken) => call((system) => system.keepLeaving(el, taken), () => constVoid),
|
|
535
|
+
awaitsTwin: (el) => call((system) => system.awaitsTwin(el), constFalse),
|
|
536
|
+
keepSeen: (el, move) => call((system) => system.keepSeen(el, move), constVoid),
|
|
537
|
+
registerValues: (el, read) => call((system) => system.registerValues(el, read), () => constVoid),
|
|
538
|
+
rootBoxOf: (el) => call((system) => system.rootBoxOf(el), Option.none),
|
|
539
|
+
dropLeaver: (el) => call((system) => system.dropLeaver(el), Option.none),
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/** A presence's work: see the module. */
|
|
544
|
+
export const makePresence = (options: PresenceOptions): PresenceController => {
|
|
545
|
+
const { runtime, reducedMotion, positionalKeys, defaultTransition } = options
|
|
546
|
+
const projection = presenceProjectionOf(options.projection)
|
|
547
|
+
const { commit, project } = options.renderer
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Debug-level lifecycle log for the parent-driven exit (observability
|
|
551
|
+
* convention): forked on the runtime, filtered out unless the logger is at
|
|
552
|
+
* Debug, so an exit that never removes its node — or a re-entry that interrupts
|
|
553
|
+
* the wrong one — is diagnosable. The per-frame commit stays silent.
|
|
554
|
+
*/
|
|
555
|
+
const debug = Report.debugOf(runtime, "wardic.presence")
|
|
556
|
+
|
|
557
|
+
// The registry of live child records, keyed by their DOM element. Filled by
|
|
558
|
+
// register() (called from the child's spine on mount), drained as children
|
|
559
|
+
// leave (after their exit settles).
|
|
560
|
+
const registry = new Map<HTMLElement, PresenceRecord>()
|
|
561
|
+
|
|
562
|
+
// In-flight exit fibers keyed by the leaving node, so a re-entry (or this
|
|
563
|
+
// component's own teardown) can interrupt them. A Map, not Effect's `FiberMap` (#618): an exit's
|
|
564
|
+
// entry goes from inside its own `ensuring`, before its fiber has ended, and is checked right after;
|
|
565
|
+
// `FiberMap.remove` interrupts the fiber it removes, and its own removal waits for the fiber's end.
|
|
566
|
+
const exiting = new Map<HTMLElement, Fiber.Fiber<void, never>>()
|
|
567
|
+
|
|
568
|
+
// A leaving child's parts still running (ADR-0010 *Amendment (#181)*): its exit, and the handovers
|
|
569
|
+
// of the twins it handed back. It goes when the count reaches 0. Every retained child that runs its
|
|
570
|
+
// own exit is here; a twin presence left to the projection isn't.
|
|
571
|
+
const pending = new Map<HTMLElement, number>()
|
|
572
|
+
// The handed-back twins of a leaving child, by it: the call that drops them, for an interrupted exit.
|
|
573
|
+
const handovers = new Map<HTMLElement, () => void>()
|
|
574
|
+
// What lets go of the twins each leaving child keeps for a late take-over (#402): called as it goes.
|
|
575
|
+
const lates = new Map<HTMLElement, () => void>()
|
|
576
|
+
// The unregistration of each exit's values with the projection.
|
|
577
|
+
const exitValues = new Map<HTMLElement, () => void>()
|
|
578
|
+
// The Wardic elements exiting inside each leaving child (#290), dropped with it.
|
|
579
|
+
const exitParts = new Map<HTMLElement, ReadonlyArray<HTMLElement>>()
|
|
580
|
+
|
|
581
|
+
// `initial={false}` (#134): the children set up with this first render start at their
|
|
582
|
+
// `animate`; one that enters after it animates in.
|
|
583
|
+
let firstRender = true
|
|
584
|
+
|
|
585
|
+
// The children exiting now, each told once at its end (#257): completed, or interrupted.
|
|
586
|
+
const leaving = new Set<HTMLElement>()
|
|
587
|
+
// Each retained child's place when it left (#277): a framework that clears its nodes wholesale (a
|
|
588
|
+
// list emptied clears its parent) takes it out mid-exit, and it goes back there.
|
|
589
|
+
const places = new Map<HTMLElement, Placed>()
|
|
590
|
+
const events = options.events
|
|
591
|
+
|
|
592
|
+
// The presence hooks registered (#277's PR 5b), each told at its child's leave.
|
|
593
|
+
const watches = new Set<PresenceWatch>()
|
|
594
|
+
|
|
595
|
+
// The children `mode="wait"` holds off the page now (#277), and the start of each ward inside one,
|
|
596
|
+
// by its element, called once the child is on the page.
|
|
597
|
+
let held: ReadonlyArray<HTMLElement> = []
|
|
598
|
+
const starts = new Map<HTMLElement, () => void>()
|
|
599
|
+
// `popLayout`'s leavers (#277), each where it was measured before the change: popped as it leaves,
|
|
600
|
+
// and kept until it's gone. Whether this change popped one, so the projection is told.
|
|
601
|
+
const pops = new Map<HTMLElement, PopBox>()
|
|
602
|
+
let popped = false
|
|
603
|
+
|
|
604
|
+
// Keys (#286, ADR-0048): each Wardic element made under this presence, told as it's made, so a
|
|
605
|
+
// child's key is known before what goes on the page is decided.
|
|
606
|
+
const made = new WeakMap<Element, Made>()
|
|
607
|
+
// The latest child exiting under each key: a child back under it takes over from that one.
|
|
608
|
+
const keyedLeavers = new Map<string | number, HTMLElement>()
|
|
609
|
+
// What each element exiting has drawn, kept by its exit's frames.
|
|
610
|
+
const draws = new Map<HTMLElement, Drawn>()
|
|
611
|
+
// The children entering now that take over from a leaver, each with that leaver: taken over at
|
|
612
|
+
// the first of their wards' mounts, or the presence's next look, whichever comes first.
|
|
613
|
+
const takeovers = new Map<HTMLElement, HTMLElement>()
|
|
614
|
+
// Where each Wardic element in a child that took over starts: read once, at its mount.
|
|
615
|
+
const seeds = new WeakMap<Element, Drawn>()
|
|
616
|
+
// The keyed leavers crossfading as twins (ADR-0010), the projection's: one taken over ends its
|
|
617
|
+
// leaving Follower at once (Q8: D).
|
|
618
|
+
const crossfades = new Set<HTMLElement>()
|
|
619
|
+
// Where each leaver taken over painted, it and the Wardic elements inside it, in the Root frame:
|
|
620
|
+
// read as the take-over is found, before the change moves anything.
|
|
621
|
+
const leaverBoxes = new Map<HTMLElement, ReadonlyMap<Element, Box.Box>>()
|
|
622
|
+
// Whether any keyed element was made: until then, no change looks for a take-over.
|
|
623
|
+
let keyed = false
|
|
624
|
+
|
|
625
|
+
/** A child's exit starts: told, and `exiting` turns on with the first. */
|
|
626
|
+
const leaveStarts = (el: HTMLElement): void => {
|
|
627
|
+
leaving.add(el)
|
|
628
|
+
if (Predicate.isUndefined(events)) return
|
|
629
|
+
if (leaving.size === 1) events.exiting(true)
|
|
630
|
+
events.exitStart()
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* A child's exit ended: with the last, `exiting` turns off, a completion is told, and the children
|
|
635
|
+
* `mode="wait"` held go on the page (#277), as Motion renders them after its `onExitComplete`.
|
|
636
|
+
*/
|
|
637
|
+
const leaveEnds = (el: HTMLElement, completed: boolean): void => {
|
|
638
|
+
if (Bool.not(leaving.delete(el))) return
|
|
639
|
+
if (leaving.size > 0) return
|
|
640
|
+
UndefinedOr.map(events, (told) => {
|
|
641
|
+
told.exiting(false)
|
|
642
|
+
if (completed) told.exitComplete()
|
|
643
|
+
})
|
|
644
|
+
// `propagate` (#277's PR 5c): the last child that left lets the parent's child go.
|
|
645
|
+
allLeft()
|
|
646
|
+
if (held.length > 0) UndefinedOr.map(options.release, (release) => release())
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// What `leaveAll` calls once none is left (#277's PR 5c), and where its children last were.
|
|
650
|
+
let onAllLeft: (() => void) | undefined
|
|
651
|
+
let anchor: Element | undefined
|
|
652
|
+
|
|
653
|
+
/** `leaveAll`'s end, told once (#277's PR 5c). */
|
|
654
|
+
const allLeft = (): void => {
|
|
655
|
+
if (Predicate.isUndefined(onAllLeft)) return
|
|
656
|
+
const done = onAllLeft
|
|
657
|
+
onAllLeft = undefined
|
|
658
|
+
done()
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/** Whether `el` is inside a child held off the page (#277). */
|
|
662
|
+
const isHeld = (el: HTMLElement): boolean => Arr.some(held, (child) => child.contains(el))
|
|
663
|
+
|
|
664
|
+
const ctx: PresenceContextValue = {
|
|
665
|
+
register: (rec) => {
|
|
666
|
+
registry.set(rec.element, rec)
|
|
667
|
+
return () => {
|
|
668
|
+
registry.delete(rec.element)
|
|
669
|
+
}
|
|
670
|
+
},
|
|
671
|
+
blocksInitial: () => options.initial() === false && firstRender,
|
|
672
|
+
watch: (watch) => {
|
|
673
|
+
watches.add(watch)
|
|
674
|
+
},
|
|
675
|
+
hold: (el, start) => {
|
|
676
|
+
if (Bool.not(isHeld(el))) return undefined
|
|
677
|
+
starts.set(el, start)
|
|
678
|
+
return () => {
|
|
679
|
+
starts.delete(el)
|
|
680
|
+
}
|
|
681
|
+
},
|
|
682
|
+
made: (el, key, twin) => {
|
|
683
|
+
made.set(el, { key, twin })
|
|
684
|
+
if (Predicate.isNotUndefined(key)) keyed = true
|
|
685
|
+
},
|
|
686
|
+
takeOverOf: (el) => {
|
|
687
|
+
settleTakeovers()
|
|
688
|
+
const seed = seeds.get(el)
|
|
689
|
+
seeds.delete(el)
|
|
690
|
+
return seed
|
|
691
|
+
},
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// Commit a projected value-map onto a retained node via the Renderer.
|
|
695
|
+
const commitValues = (el: HTMLElement, values: Values.Values): void => {
|
|
696
|
+
const patch: Renderer.Patch = project(values)
|
|
697
|
+
commit(el, patch)
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
// Remove a retained node from the DOM + drop its registration + clear its
|
|
701
|
+
// in-flight fiber bookkeeping. Idempotent. `completed`: its exit ended on its own (#257).
|
|
702
|
+
const finishExit = (el: HTMLElement, completed = true): void => {
|
|
703
|
+
exiting.delete(el)
|
|
704
|
+
registry.delete(el)
|
|
705
|
+
draws.delete(el)
|
|
706
|
+
crossfades.delete(el)
|
|
707
|
+
leaverBoxes.delete(el)
|
|
708
|
+
// No longer one a child back under its key takes over from (#286).
|
|
709
|
+
UndefinedOr.map(keyOf(el), (key) => {
|
|
710
|
+
if (keyedLeavers.get(key) === el) keyedLeavers.delete(key)
|
|
711
|
+
})
|
|
712
|
+
pending.delete(el)
|
|
713
|
+
handovers.delete(el)
|
|
714
|
+
UndefinedOr.map(lates.get(el), (forget) => forget())
|
|
715
|
+
lates.delete(el)
|
|
716
|
+
places.delete(el)
|
|
717
|
+
// A popped leaver is out of the flow: its going moves nothing.
|
|
718
|
+
const moves = Bool.and(el.isConnected, Bool.not(pops.delete(el)))
|
|
719
|
+
const unregister = exitValues.get(el)
|
|
720
|
+
exitValues.delete(el)
|
|
721
|
+
if (Predicate.isNotUndefined(unregister)) unregister()
|
|
722
|
+
// The elements inside it that exited with it go with it (#290): their records, and their values.
|
|
723
|
+
Arr.forEach(UndefinedOr.match(exitParts.get(el), { onUndefined: () => NO_PARTS, onDefined: identity }), (part) => {
|
|
724
|
+
registry.delete(part)
|
|
725
|
+
draws.delete(part)
|
|
726
|
+
UndefinedOr.map(exitValues.get(part), (unregisterPart) => unregisterPart())
|
|
727
|
+
exitValues.delete(part)
|
|
728
|
+
})
|
|
729
|
+
exitParts.delete(el)
|
|
730
|
+
el.remove()
|
|
731
|
+
// Its siblings take the space it leaves (#277): a `layout` one animates there, as Motion's do.
|
|
732
|
+
if (Bool.and(moves, affectsLayout())) projection.notify()
|
|
733
|
+
// Told once the node is gone, as Motion's `onExitComplete` finds it (#257).
|
|
734
|
+
leaveEnds(el, completed)
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// One of a leaving child's parts ended (#181): it goes with the last. A child already removed
|
|
738
|
+
// (an interrupted exit's fiber ending after) is ignored.
|
|
739
|
+
const partDone = (el: HTMLElement): void => {
|
|
740
|
+
const left = pending.get(el)
|
|
741
|
+
if (Predicate.isUndefined(left)) return
|
|
742
|
+
if (left > 1) {
|
|
743
|
+
pending.set(el, left - 1)
|
|
744
|
+
return
|
|
745
|
+
}
|
|
746
|
+
finishExit(el)
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// Interrupt an in-flight exit for `el` (re-entry / teardown) and remove the
|
|
750
|
+
// retained node, the twins it handed back dropped with it. Idempotent.
|
|
751
|
+
const interruptExit = (el: HTMLElement): void => {
|
|
752
|
+
// Told first, as interrupted: the exit's fiber, interrupted below, ends at once through
|
|
753
|
+
// `partDone`, which would tell it completed (#257).
|
|
754
|
+
leaveEnds(el, false)
|
|
755
|
+
const fiber = exiting.get(el)
|
|
756
|
+
if (Predicate.isNotUndefined(fiber)) {
|
|
757
|
+
debug("exit: interrupt")
|
|
758
|
+
// Nothing waits on its end: interrupted here, not by a fiber forked for it (#618, L2).
|
|
759
|
+
fiber.interruptUnsafe()
|
|
760
|
+
}
|
|
761
|
+
const drop = handovers.get(el)
|
|
762
|
+
if (Predicate.isNotUndefined(drop)) drop()
|
|
763
|
+
finishExit(el, false)
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
// A leaving child that isn't a twin (ADR-0010 *Amendment (#181)*): it hands back the twins inside
|
|
767
|
+
// it, then runs its own exit and the exits inside it, and goes once all have ended. A plain child
|
|
768
|
+
// (not a Wardic element, no `rec`) runs only those inside it (#392), as Motion's presence child does.
|
|
769
|
+
const leave = (el: HTMLElement, rec: PresenceRecord | undefined, custom: unknown, inside: ReadonlyArray<PresenceWatch>, holds: number): void => {
|
|
770
|
+
// A keyed one is what a child back under its key takes over from (#286), the latest the one.
|
|
771
|
+
UndefinedOr.map(keyOf(el), (key) => keyedLeavers.set(key, el))
|
|
772
|
+
const drop = projection.handBackWithin(el, () => partDone(el))
|
|
773
|
+
// Its parts: its exit, each hook holding it (#277's PR 5b), and the handovers of the twins it hands back.
|
|
774
|
+
pending.set(el, 1 + holds)
|
|
775
|
+
if (Option.isSome(drop)) {
|
|
776
|
+
handovers.set(el, drop.value)
|
|
777
|
+
pending.set(el, 2 + holds)
|
|
778
|
+
debug("leave: hands back its twins")
|
|
779
|
+
}
|
|
780
|
+
// The twins nobody took over stay a later twin's to take over while it's on the page (#402).
|
|
781
|
+
lates.set(el, projection.keepLeaving(el, (dropLate) => takenLate(el, dropLate)))
|
|
782
|
+
tellLeave(el, inside, true)
|
|
783
|
+
driveExit(el, rec, custom)
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// A twin in a leaving child taken over late (ADR-0010 *Amendment (#402)*): one more of its parts,
|
|
787
|
+
// ended with that handover, and dropped with its others by an interrupted exit. Its own exit runs on:
|
|
788
|
+
// the handover draws the twin over it.
|
|
789
|
+
const takenLate = (el: HTMLElement, drop: () => void): (() => void) => {
|
|
790
|
+
const left = pending.get(el)
|
|
791
|
+
if (Predicate.isUndefined(left)) {
|
|
792
|
+
drop()
|
|
793
|
+
return constVoid
|
|
794
|
+
}
|
|
795
|
+
pending.set(el, left + 1)
|
|
796
|
+
const before = handovers.get(el)
|
|
797
|
+
handovers.set(el, () => {
|
|
798
|
+
UndefinedOr.map(before, (dropBefore) => dropBefore())
|
|
799
|
+
drop()
|
|
800
|
+
})
|
|
801
|
+
debug("leave: a twin taken over late")
|
|
802
|
+
return () => partDone(el)
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* The Wardic elements inside a leaving child (#290), in document order, each running its own exit
|
|
807
|
+
* with the child's: every registered one but a twin, whose crossfade replaces its exit (#181).
|
|
808
|
+
*/
|
|
809
|
+
const partsOf = (el: HTMLElement): ReadonlyArray<PresenceRecord> => Arr.filter(registeredWithin(el), isPart)
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* The records of the elements inside `el`, in document order, `undefined` for one not registered:
|
|
813
|
+
* found by walking its own elements (#392), as many steps as it has, not as the presence has records.
|
|
814
|
+
*/
|
|
815
|
+
const registeredWithin = (el: HTMLElement): ReadonlyArray<PresenceRecord | undefined> => {
|
|
816
|
+
if (registry.size === 0) return NO_RECORDS
|
|
817
|
+
return Arr.map(Arr.fromIterable(el.getElementsByTagName("*")), (inner) => registry.get(inner as HTMLElement))
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
/** A registered element but a twin. */
|
|
821
|
+
const isPart = (part: PresenceRecord | undefined): part is PresenceRecord => {
|
|
822
|
+
if (Predicate.isUndefined(part)) return false
|
|
823
|
+
return Bool.not(treeOf(part).twin)
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Whether a leaving child stays to exit (#392): a Wardic element, or a plain one with something
|
|
828
|
+
* inside it to wait for, a Wardic element (an exit to run, a twin to hand back) or a hook's hold.
|
|
829
|
+
*/
|
|
830
|
+
const retains = (el: HTMLElement): boolean => {
|
|
831
|
+
if (registry.has(el)) return true
|
|
832
|
+
if (holdsIn(el)) return true
|
|
833
|
+
return registersWithin(el)
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/** Whether a Wardic element made under this presence is inside `el`. */
|
|
837
|
+
const registersWithin = (el: HTMLElement): boolean => Arr.some(registeredWithin(el), Predicate.isNotUndefined)
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* A leaving child's exit, and the exits inside it (#290), as Motion's `animateVariant` runs them:
|
|
841
|
+
* each element's own exit, its Variant children's on the name it hands down, in its exit
|
|
842
|
+
* orchestration (`delayChildren`, the stagger, `when`), and every other element's from the leave.
|
|
843
|
+
* A plain child (no `rec`) has no exit of its own: the elements inside it are the roots (#392).
|
|
844
|
+
* The child goes once all of them, and the handovers of the twins it handed back, have ended.
|
|
845
|
+
*/
|
|
846
|
+
const driveExit = (el: HTMLElement, rec: PresenceRecord | undefined, custom: unknown): void => {
|
|
847
|
+
const parts = partsOf(el)
|
|
848
|
+
exitParts.set(el, Arr.map(parts, (part) => part.element))
|
|
849
|
+
const own = UndefinedOr.match(rec, { onUndefined: () => NO_OWN, onDefined: Arr.of })
|
|
850
|
+
const byElement = new Map<Element, PresenceRecord>(Arr.map([...own, ...parts], (r) => [r.element, r] as const))
|
|
851
|
+
// The nearest element inside the child its Variant children join: one that provides a context.
|
|
852
|
+
const providerOf = (node: Element | null): PresenceRecord | undefined => {
|
|
853
|
+
if (node === null) return undefined
|
|
854
|
+
const found = byElement.get(node)
|
|
855
|
+
if (Predicate.isNotUndefined(found) && treeOf(found).provides) return found
|
|
856
|
+
if (node === el) return undefined
|
|
857
|
+
return providerOf(node.parentElement)
|
|
858
|
+
}
|
|
859
|
+
const joinsTo = new Map<PresenceRecord, PresenceRecord>()
|
|
860
|
+
Arr.forEach(parts, (part) => {
|
|
861
|
+
if (Bool.not(treeOf(part).joins)) return
|
|
862
|
+
UndefinedOr.map(providerOf(part.element.parentElement), (provider) => joinsTo.set(part, provider))
|
|
863
|
+
})
|
|
864
|
+
const joinersOf = (provider: PresenceRecord): ReadonlyArray<PresenceRecord> => Arr.filter(parts, (part) => joinsTo.get(part) === provider)
|
|
865
|
+
const nodeOf = (node: PresenceRecord, inherited: WardicVariantLabels | undefined): ExitNode => {
|
|
866
|
+
const exit = node.exitOf(custom, inherited)
|
|
867
|
+
return { rec: node, exit, kids: Arr.map(joinersOf(node), (kid) => nodeOf(kid, exit.name)) }
|
|
868
|
+
}
|
|
869
|
+
// The child's own tree, if it's a Wardic element, and each element inside it that joins nothing
|
|
870
|
+
// inside it, from the leave.
|
|
871
|
+
const roots = [
|
|
872
|
+
...Arr.map(own, (r) => nodeOf(r, undefined)),
|
|
873
|
+
...Arr.map(Arr.filter(parts, (part) => Bool.not(joinsTo.has(part))), (part) => nodeOf(part, undefined)),
|
|
874
|
+
]
|
|
875
|
+
if (Bool.not(Arr.some(roots, busy))) {
|
|
876
|
+
debug("exit: immediate (no target)")
|
|
877
|
+
partDone(el)
|
|
878
|
+
return
|
|
879
|
+
}
|
|
880
|
+
// One `wardic.presence.exit` span spans the whole exit, from the leave to the last part's end.
|
|
881
|
+
// A failed run is logged and reported (ADR-0030, decision 4); the node is removed either way.
|
|
882
|
+
const fiber = runtime.runFork(
|
|
883
|
+
Effect.all(Arr.map(roots, (root) => runOf(root, NO_DELAY)), { concurrency: "unbounded", discard: true }).pipe(
|
|
884
|
+
Effect.tapCause((cause) => Report.failure("wardic.presence: an exit failed", cause)),
|
|
885
|
+
Effect.ensuring(Effect.sync(() => partDone(el))),
|
|
886
|
+
Effect.withSpan(
|
|
887
|
+
"wardic.presence.exit",
|
|
888
|
+
{ attributes: { parts: parts.length + own.length } },
|
|
889
|
+
// No call-site stack (ADR-0040, decision 2): pipeable, it's the third argument.
|
|
890
|
+
{ captureStackTrace: false },
|
|
891
|
+
),
|
|
892
|
+
),
|
|
893
|
+
)
|
|
894
|
+
exiting.set(el, fiber)
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* A node's exit and its Variant children's (#290), Motion's `animateVariant`: with `when`, one after
|
|
899
|
+
* the other, the children's delays from 0; else together, the children's from `delay`.
|
|
900
|
+
*/
|
|
901
|
+
const runOf = (node: ExitNode, delay: DelayOf): Effect.Effect<unknown, never, WardicServices> => {
|
|
902
|
+
// A list's names each run on their own (#297's PR 2): each name's keys and its children's, in that
|
|
903
|
+
// name's own `when`.
|
|
904
|
+
const groups = node.exit.groups
|
|
905
|
+
if (Predicate.isNotUndefined(groups)) {
|
|
906
|
+
const first = UndefinedOr.match(groups[0], { onUndefined: constUndefined, onDefined: (group) => group.name })
|
|
907
|
+
return Effect.all(Arr.map(groups, (group) => runName(node, group.name, delay, group.name === first)), { concurrency: "unbounded", discard: true })
|
|
908
|
+
}
|
|
909
|
+
const own = exitOf(node.rec, node.exit, delay)
|
|
910
|
+
if (node.kids.length === 0) return own
|
|
911
|
+
const n = node.kids.length
|
|
912
|
+
// Each name orchestrates the children's keys of that name (#297, Motion's `animateVariant` a name):
|
|
913
|
+
// its own transition's delay and stagger, else the exit's.
|
|
914
|
+
const slot = (i: number) => (name: string | undefined): number => {
|
|
915
|
+
const s = staggerOf(transitionOfName(node.exit, name))
|
|
916
|
+
return childDelayOf(s, i, n)
|
|
917
|
+
}
|
|
918
|
+
const kidsFrom = (from: DelayOf): Effect.Effect<unknown, never, WardicServices> =>
|
|
919
|
+
Effect.all(Arr.map(node.kids, (kid, i) => runOf(kid, (name) => from(name) + slot(i)(name))), { concurrency: "unbounded", discard: true })
|
|
920
|
+
// `when` for a list as a whole, meanwhile (#297's PR 1): the exit's, its last name's that sets it.
|
|
921
|
+
const when = UndefinedOr.map(node.exit.transition, (t) => t.when)
|
|
922
|
+
if (when === "beforeChildren") return Effect.andThen(own, kidsFrom(NO_DELAY))
|
|
923
|
+
if (when === "afterChildren") return Effect.andThen(kidsFrom(NO_DELAY), own)
|
|
924
|
+
return Effect.all([own, kidsFrom(delay)], { concurrency: "unbounded", discard: true })
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* One name of a list's exit (#297's PR 2, Motion's `animateVariant` a name): the element's keys of that
|
|
929
|
+
* name, and its Variant children's, one after the other with that name's `when`, else together. A
|
|
930
|
+
* child whose exit isn't the list runs it whole, under the list's first name.
|
|
931
|
+
*/
|
|
932
|
+
const runName = (node: ExitNode, name: string, delay: DelayOf, first: boolean): Effect.Effect<unknown, never, WardicServices> => {
|
|
933
|
+
const own = exitOf(node.rec, node.exit, delay, name)
|
|
934
|
+
const n = node.kids.length
|
|
935
|
+
if (n === 0) return own
|
|
936
|
+
const slot = (i: number) => (of: string | undefined): number => {
|
|
937
|
+
const s = staggerOf(transitionOfName(node.exit, of))
|
|
938
|
+
return childDelayOf(s, i, n)
|
|
939
|
+
}
|
|
940
|
+
const kidsFrom = (from: DelayOf): Effect.Effect<unknown, never, WardicServices> =>
|
|
941
|
+
Effect.all(
|
|
942
|
+
Arr.map(node.kids, (kid, i) => {
|
|
943
|
+
const at: DelayOf = (of) => from(of) + slot(i)(of)
|
|
944
|
+
if (Predicate.isNotUndefined(kid.exit.groups)) return runName(kid, name, at, first)
|
|
945
|
+
if (first) return runOf(kid, at)
|
|
946
|
+
return Effect.void
|
|
947
|
+
}),
|
|
948
|
+
{ concurrency: "unbounded", discard: true },
|
|
949
|
+
)
|
|
950
|
+
const when = UndefinedOr.map(transitionOfName(node.exit, name), (t) => t.when)
|
|
951
|
+
if (when === "beforeChildren") return Effect.andThen(own, kidsFrom(NO_DELAY))
|
|
952
|
+
if (when === "afterChildren") return Effect.andThen(kidsFrom(NO_DELAY), own)
|
|
953
|
+
return Effect.all([own, kidsFrom(delay)], { concurrency: "unbounded", discard: true })
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* One element's own exit on its retained node, `delay` seconds in (#290): a Retarget's legs (#277),
|
|
958
|
+
* on the exit's own transition, else the element's, its positional keys snapping under reduced
|
|
959
|
+
* motion (ADR-0029) unless it opts out. Nothing to run for an empty one.
|
|
960
|
+
*/
|
|
961
|
+
const exitOf = (rec: PresenceRecord, exit: PresenceExit, delay: DelayOf, only?: string): Effect.Effect<unknown, never, WardicServices> => {
|
|
962
|
+
const to = exit.values
|
|
963
|
+
if (isEmpty(to)) return Effect.void
|
|
964
|
+
const { from, stops, commitFrame, velocities, el } = preparedOf(rec, exit)
|
|
965
|
+
// Its keys start with the velocity their frames gave them (#464, Motion's): 0 for one at rest.
|
|
966
|
+
const moving = velocitiesOf(UndefinedOr.match(rec.velocities, { onUndefined: () => NO_VELOCITIES, onDefined: (of) => of() }))
|
|
967
|
+
// A list's exit by name (#297): each name's keys on its own transition, at its own delay; one
|
|
968
|
+
// name's alone when its `when` orders it (#297's PR 2).
|
|
969
|
+
// The leaver's own, under its nearest WardicConfig (#434), else the presence's.
|
|
970
|
+
const reduce = UndefinedOr.match(rec.reducedMotion, { onUndefined: reducedMotion, onDefined: (own) => own() })
|
|
971
|
+
// Skipped (#468): every key lands at its end on the first tick, and the element leaves then.
|
|
972
|
+
const skipped = UndefinedOr.match(rec.skipAnimations, { onUndefined: constFalse, onDefined: (own) => own() })
|
|
973
|
+
// Measured pairs (#430): an exit from `auto` to 0 measures both ends, as a Retarget does, unless
|
|
974
|
+
// reduced motion snaps them or the exit is skipped.
|
|
975
|
+
const measured = Bool.match(Bool.or(reduce, skipped), { onTrue: constUndefined, onFalse: () => exitMeasuredOf(el, from, to, stops) })
|
|
976
|
+
const legs = UndefinedOr.match(exit.groups, {
|
|
977
|
+
onUndefined: () => legsOf(from, to, delayedBy(exit.transition, delay(singleNameOf(exit.name))), reduce, skipped, positionalKeys, defaultTransition, moving, undefined, stops, measured),
|
|
978
|
+
onDefined: (groups) =>
|
|
979
|
+
Arr.flatMap(
|
|
980
|
+
Arr.filter(groups, (group) => Bool.or(Predicate.isUndefined(only), group.name === only)),
|
|
981
|
+
(group: ExitGroup) => legsOf(from, group.values, delayedBy(group.transition, delay(group.name)), reduce, skipped, positionalKeys, defaultTransition, moving, undefined, stops, measured),
|
|
982
|
+
),
|
|
983
|
+
})
|
|
984
|
+
return Effect.all(Arr.map(legs, (leg) => exitRunOf(leg, el, commitFrame, velocities)), { concurrency: "unbounded", discard: true })
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// Each exit's start, made once though a list's names run its keys apart (#297's PR 2).
|
|
988
|
+
const prepared = new WeakMap<PresenceExit, PreparedExit>()
|
|
989
|
+
|
|
990
|
+
/** An element's exit made ready to run: where it starts, and what each frame commits. */
|
|
991
|
+
const preparedOf = (rec: PresenceRecord, exit: PresenceExit): PreparedExit => {
|
|
992
|
+
const known = prepared.get(exit)
|
|
993
|
+
if (Predicate.isNotUndefined(known)) return known
|
|
994
|
+
const el = rec.element
|
|
995
|
+
const to = exit.values
|
|
996
|
+
// Seeded from the element's last snapshot, so its exit departs continuously. A key it never
|
|
997
|
+
// animated starts from its Base value's start links (ADR-0022), else at its target.
|
|
998
|
+
const snapshot = rec.snapshot.current
|
|
999
|
+
const startOf = (key: string, target: number | string): number | string =>
|
|
1000
|
+
UndefinedOr.match(UndefinedOr.match(rec.startOf, { onUndefined: constUndefined, onDefined: (of) => of(key, target) }), {
|
|
1001
|
+
onUndefined: () => target,
|
|
1002
|
+
onDefined: identity,
|
|
1003
|
+
})
|
|
1004
|
+
const seeded: Values.Values = {
|
|
1005
|
+
...snapshot,
|
|
1006
|
+
...Rec.map(Rec.filter(to, (_, key) => Predicate.isUndefined(snapshot[key])), (target, key) => startOf(key, target)),
|
|
1007
|
+
}
|
|
1008
|
+
// Its Keyframes (#429) start at their first stop, a `null` one where the key is.
|
|
1009
|
+
const { from, stops } = UndefinedOr.match(exit.keyframes, {
|
|
1010
|
+
onUndefined: () => ({ from: seeded, stops: undefined }),
|
|
1011
|
+
onDefined: (keyframes) => keyframesFrom(seeded, to, keyframes),
|
|
1012
|
+
})
|
|
1013
|
+
// The merged latest value-map, so each committed frame carries every key.
|
|
1014
|
+
const latest: Values.Values = { ...from }
|
|
1015
|
+
// What the exit has drawn, for the projection (ADR-0010 *Amendment (#181)*): the twins handed back
|
|
1016
|
+
// follow it. Its last snapshot until the first frame commits.
|
|
1017
|
+
const drawn: Values.Values = { ...from }
|
|
1018
|
+
UndefinedOr.map(exitValues.get(el), (unregister) => unregister())
|
|
1019
|
+
exitValues.set(el, projection.registerValues(el, () => drawn))
|
|
1020
|
+
// And how fast each key moves (#286): a child back under its key starts with it.
|
|
1021
|
+
const velocities: Record<string, number> = {}
|
|
1022
|
+
draws.set(el, { values: drawn, velocities })
|
|
1023
|
+
const commitFrame: FrameLoop.Sink<Frame.Frame<Values.Values>> = (frame) => {
|
|
1024
|
+
Object.assign(latest, frame.value)
|
|
1025
|
+
commitValues(el, latest)
|
|
1026
|
+
Object.assign(drawn, latest)
|
|
1027
|
+
return undefined
|
|
1028
|
+
}
|
|
1029
|
+
const made: PreparedExit = { el, from, stops, commitFrame, velocities }
|
|
1030
|
+
prepared.set(exit, made)
|
|
1031
|
+
return made
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
// The children present at the last change, and where each was, to retain one as it leaves.
|
|
1035
|
+
let previous: ReadonlyArray<Placed> = []
|
|
1036
|
+
// The children as the last change left them (#486): those on the page, the leavers among them.
|
|
1037
|
+
let rendered: ReadonlyArray<HTMLElement> = []
|
|
1038
|
+
|
|
1039
|
+
// Teardown: interrupt every in-flight exit + remove retained nodes, the twins they handed back
|
|
1040
|
+
// dropped with them (no leaks). Every child running its own exit is in `pending`.
|
|
1041
|
+
const teardown = (): void => {
|
|
1042
|
+
debug("teardown", { inflight: exiting.size, retained: pending.size })
|
|
1043
|
+
// A held child never goes on the page, nor do its wards start (#277): with none held, the exits
|
|
1044
|
+
// ended below release nothing, so the binding isn't rendered again as it's disposed.
|
|
1045
|
+
held = []
|
|
1046
|
+
starts.clear()
|
|
1047
|
+
// The hooks still waiting go with it, told nothing left (#277's PR 5b).
|
|
1048
|
+
Arr.forEach(Arr.fromIterable(watches), (watch) => watch.gone())
|
|
1049
|
+
watches.clear()
|
|
1050
|
+
// Each retained child, a leave waiting for its task's end (#482) among them.
|
|
1051
|
+
Arr.forEach(Arr.fromIterable(new Set([...pending.keys(), ...exiting.keys()])), (el) => interruptExit(el))
|
|
1052
|
+
// A crossfading leaver is the projection's, not in `pending`: its exit ends here too, uncompleted (#257).
|
|
1053
|
+
Arr.forEach(Arr.fromIterable(leaving), (el) => leaveEnds(el, false))
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
/** Whether a hook inside `el` holds it as it leaves (#277's PR 5b). */
|
|
1057
|
+
const holdsIn = (el: HTMLElement): boolean => Arr.some(watchesIn(el), (watch) => watch.holds)
|
|
1058
|
+
|
|
1059
|
+
/** A record whose element is off the page, dropped; a leaver's is put back first, so it stays. */
|
|
1060
|
+
const dropDetached = (el: HTMLElement): void => {
|
|
1061
|
+
if (el.isConnected) return
|
|
1062
|
+
registry.delete(el)
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
/** Pop a leaver `popLayout` measured. */
|
|
1066
|
+
const popOut = (el: HTMLElement): void => {
|
|
1067
|
+
const box = pops.get(el)
|
|
1068
|
+
if (Predicate.isUndefined(box)) return
|
|
1069
|
+
pin(el, box)
|
|
1070
|
+
// Where it was seen, through the page's scroll at this change: a router's to the top (#480).
|
|
1071
|
+
projection.keepSeen(el, (by) => movePin(el, box, by))
|
|
1072
|
+
popped = true
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
/**
|
|
1076
|
+
* Measure each child leaving in this change that stays to exit, before the change is applied (#277):
|
|
1077
|
+
* a plain one too, with something inside it to wait for (#392).
|
|
1078
|
+
*/
|
|
1079
|
+
const measureLeavers = (resolved: unknown): void => {
|
|
1080
|
+
const kept = new Set(elementsOf(resolved))
|
|
1081
|
+
// Its anchors now (#442).
|
|
1082
|
+
const anchors: PopAnchors = {
|
|
1083
|
+
x: UndefinedOr.match(UndefinedOr.map(options.anchorX, (read) => read()), { onUndefined: (): PopAnchors["x"] => "left", onDefined: identity }),
|
|
1084
|
+
y: UndefinedOr.match(UndefinedOr.map(options.anchorY, (read) => read()), { onUndefined: (): PopAnchors["y"] => "top", onDefined: identity }),
|
|
1085
|
+
}
|
|
1086
|
+
Arr.forEach(previous, (placed) => {
|
|
1087
|
+
if (kept.has(placed.el)) return
|
|
1088
|
+
if (Bool.not(retains(placed.el))) return
|
|
1089
|
+
UndefinedOr.map(popBoxOf(placed.el, anchors), (box) => pops.set(placed.el, box))
|
|
1090
|
+
})
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
/** Put a retained child back where it was, if a framework took it out. */
|
|
1094
|
+
const putBack = (placed: Placed): void => {
|
|
1095
|
+
if (placed.el.parentNode !== null) return
|
|
1096
|
+
UndefinedOr.map(placed.parent, (parent) => reinsert(placed.el, parent, placed.next))
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
/** A child that left: retained at `back` (#486), and exiting, unless it's leaving already. */
|
|
1100
|
+
const left = (placed: Placed, back: Placed): void => {
|
|
1101
|
+
const el = placed.el
|
|
1102
|
+
const rec = registry.get(el)
|
|
1103
|
+
// The presence hooks inside it (#277's PR 5b): told it left; `usePresence`'s hold it until released.
|
|
1104
|
+
const inside = watchesIn(el)
|
|
1105
|
+
const holds = Arr.filter(inside, (watch) => watch.holds).length
|
|
1106
|
+
// A plain child (not a Wardic element) with nothing inside it to wait for, no Wardic element
|
|
1107
|
+
// (an exit to run, a twin to hand back) and no hook holding it, is gone at once (#257, #392).
|
|
1108
|
+
if (Bool.and(Predicate.isUndefined(rec), holds === 0)) {
|
|
1109
|
+
if (Bool.not(registersWithin(el))) {
|
|
1110
|
+
if (Bool.not(leaving.has(el))) {
|
|
1111
|
+
leaveStarts(el)
|
|
1112
|
+
tellLeave(el, inside, false)
|
|
1113
|
+
leaveEnds(el, true)
|
|
1114
|
+
}
|
|
1115
|
+
return
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
if (Bool.or(exiting.has(el), pending.has(el))) return
|
|
1119
|
+
leaveStarts(el)
|
|
1120
|
+
// RE-INSERT: Solid's branch disposal may have already removed the node. Put it back, so the
|
|
1121
|
+
// parent-driven exit has a mounted node to animate: at `back`, moved there if Solid left it in.
|
|
1122
|
+
UndefinedOr.map(back.parent, (parent) => reinsert(el, parent, back.next))
|
|
1123
|
+
places.set(el, placedOf(el))
|
|
1124
|
+
// `popLayout` (#277): out of the flow where it was, so the children after it take their places.
|
|
1125
|
+
popOut(el)
|
|
1126
|
+
// A twin it is or holds left with none to take it over yet (ADR-0010 *Amendment (#482)*): its
|
|
1127
|
+
// partner may arrive later in this update, as Solid runs a presence before the children it mounts.
|
|
1128
|
+
// So it's decided at the task's end, before a frame, and stays on the page till then, an exit-less
|
|
1129
|
+
// one too, as Motion keeps its relegated leaver until `postRender`.
|
|
1130
|
+
if (projection.awaitsTwin(el)) {
|
|
1131
|
+
// Keyed, it's what a child back under its key in this update takes over from (#286), meanwhile too.
|
|
1132
|
+
UndefinedOr.map(keyOf(el), (key) => keyedLeavers.set(key, el))
|
|
1133
|
+
decideAtTaskEnd(el, () => decideLeave(el, rec, inside, holds))
|
|
1134
|
+
return
|
|
1135
|
+
}
|
|
1136
|
+
decideLeave(el, rec, inside, holds)
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
/** A leave decided at the task's end (#482): kept as `exiting`, so a re-entry or the teardown interrupts it. */
|
|
1140
|
+
const decideAtTaskEnd = (el: HTMLElement, decide: () => void): void => {
|
|
1141
|
+
const fiber = runtime.runFork(
|
|
1142
|
+
Microtask.next.pipe(
|
|
1143
|
+
Effect.andThen(
|
|
1144
|
+
Effect.sync(() => {
|
|
1145
|
+
exiting.delete(el)
|
|
1146
|
+
decide()
|
|
1147
|
+
}),
|
|
1148
|
+
),
|
|
1149
|
+
),
|
|
1150
|
+
)
|
|
1151
|
+
exiting.set(el, fiber)
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
/** What a retained leaver does: crossfade onto its twin, or run its exit, or hand back the twins inside it. */
|
|
1155
|
+
const decideLeave = (el: HTMLElement, rec: PresenceRecord | undefined, inside: ReadonlyArray<PresenceWatch>, holds: number): void => {
|
|
1156
|
+
// A plain child (#392): retained, as Motion's presence child, until the exits inside it, the
|
|
1157
|
+
// handovers of its twins and the hooks holding it (#277's PR 5b) have all ended.
|
|
1158
|
+
if (Predicate.isUndefined(rec)) {
|
|
1159
|
+
leave(el, undefined, customNow(), inside, holds)
|
|
1160
|
+
return
|
|
1161
|
+
}
|
|
1162
|
+
// Shared-element crossfade (ADR-0010): if the projection has a live twin (Lead) to crossfade
|
|
1163
|
+
// toward, defer to it — it drives the retained node as a leaving Follower and calls onDone
|
|
1164
|
+
// (-> finishExit) on the lead's settle. Otherwise run the normal exit animation. A crossfading
|
|
1165
|
+
// child goes with its handover: the hooks inside it are told, but don't hold it.
|
|
1166
|
+
const crossfaded = projection.handleLeave(el, () => finishExit(el))
|
|
1167
|
+
if (crossfaded) {
|
|
1168
|
+
debug("leave: crossfade (deferred to projection)")
|
|
1169
|
+
tellLeave(el, inside, false)
|
|
1170
|
+
// A keyed one is what a child back under its key takes over from (#286), its Follower ended.
|
|
1171
|
+
UndefinedOr.map(keyOf(el), (key) => {
|
|
1172
|
+
keyedLeavers.set(key, el)
|
|
1173
|
+
crossfades.add(el)
|
|
1174
|
+
})
|
|
1175
|
+
return
|
|
1176
|
+
}
|
|
1177
|
+
// Its exit, resolved now (#277): with the presence's `custom` when it has one, else the child's last.
|
|
1178
|
+
leave(el, rec, customNow(), inside, holds)
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
/** The presence hooks inside `el` (#277's PR 5b): those whose element it holds. */
|
|
1182
|
+
const watchesIn = (el: HTMLElement): ReadonlyArray<PresenceWatch> =>
|
|
1183
|
+
Arr.filter(Arr.fromIterable(watches), (watch) => UndefinedOr.match(watch.element(), { onUndefined: constFalse, onDefined: (at) => el.contains(at) }))
|
|
1184
|
+
|
|
1185
|
+
/**
|
|
1186
|
+
* Tell the hooks inside a leaving child it left (#277's PR 5b), with the presence's `custom`. With
|
|
1187
|
+
* `counted`, each that holds it is one of its parts, ended by its release (once). A callback that
|
|
1188
|
+
* throws is reported, and lets the child go.
|
|
1189
|
+
*/
|
|
1190
|
+
const tellLeave = (el: HTMLElement, inside: ReadonlyArray<PresenceWatch>, counted: boolean): void => {
|
|
1191
|
+
const custom = customNow()
|
|
1192
|
+
Arr.forEach(inside, (watch) => {
|
|
1193
|
+
watches.delete(watch)
|
|
1194
|
+
let released = false
|
|
1195
|
+
const release = (): void => {
|
|
1196
|
+
if (released) return
|
|
1197
|
+
released = true
|
|
1198
|
+
if (Bool.and(counted, watch.holds)) partDone(el)
|
|
1199
|
+
}
|
|
1200
|
+
try {
|
|
1201
|
+
watch.leave(custom, release)
|
|
1202
|
+
} catch (defect) {
|
|
1203
|
+
runtime.runFork(Report.failure("wardic.presence: a usePresence callback failed", Cause.die(defect)))
|
|
1204
|
+
release()
|
|
1205
|
+
}
|
|
1206
|
+
})
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
/** A hook whose element left the page some other way, dropped (#277's PR 5b): not one a held child holds. */
|
|
1210
|
+
const dropDetachedWatch = (watch: PresenceWatch): void => {
|
|
1211
|
+
UndefinedOr.map(watch.element(), (at) => {
|
|
1212
|
+
if (Bool.or(at.isConnected, isHeld(at as HTMLElement))) return
|
|
1213
|
+
watches.delete(watch)
|
|
1214
|
+
watch.gone()
|
|
1215
|
+
})
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
// --- Keys (#286, ADR-0048) ------------------------------------------------
|
|
1219
|
+
|
|
1220
|
+
/** An element's `key`, told as it was made: `undefined` for one with none, or not a Wardic element. */
|
|
1221
|
+
const keyOf = (el: Element): string | number | undefined => UndefinedOr.map(made.get(el), (m) => m.key)
|
|
1222
|
+
|
|
1223
|
+
/**
|
|
1224
|
+
* Where a Wardic element is drawn: what its exit has drawn, if it's exiting, over its last values;
|
|
1225
|
+
* else its last values, at the velocities its own animation left them.
|
|
1226
|
+
*/
|
|
1227
|
+
const drawnOf = (rec: PresenceRecord): Drawn =>
|
|
1228
|
+
UndefinedOr.match(draws.get(rec.element), {
|
|
1229
|
+
onUndefined: (): Drawn => ({
|
|
1230
|
+
values: valuesDrawn(rec.snapshot.current),
|
|
1231
|
+
velocities: UndefinedOr.match(rec.velocities, { onUndefined: () => NO_VELOCITIES, onDefined: (of) => ({ ...of() }) }),
|
|
1232
|
+
}),
|
|
1233
|
+
onDefined: (drawn): Drawn => ({ values: valuesDrawn({ ...rec.snapshot.current, ...drawn.values }), velocities: { ...drawn.velocities } }),
|
|
1234
|
+
})
|
|
1235
|
+
|
|
1236
|
+
/** The Wardic elements made under this presence inside `el`, in document order, but the twins (#181). */
|
|
1237
|
+
const madeWithin = (el: HTMLElement): ReadonlyArray<Element> =>
|
|
1238
|
+
Arr.filter(Arr.fromIterable(el.querySelectorAll("*")), (inner) =>
|
|
1239
|
+
UndefinedOr.match(made.get(inner), { onUndefined: constFalse, onDefined: (m) => Bool.not(m.twin) }))
|
|
1240
|
+
|
|
1241
|
+
/**
|
|
1242
|
+
* The children entering in this change that take over from a leaver: one with the key of a child
|
|
1243
|
+
* exiting, or of one leaving in this change (Motion keeps an element whose key stays).
|
|
1244
|
+
*/
|
|
1245
|
+
const findTakeovers = (resolved: unknown): void => {
|
|
1246
|
+
const onPage = new Set(Arr.map(previous, (placed) => placed.el))
|
|
1247
|
+
const now = elementsOf(resolved)
|
|
1248
|
+
const kept = new Set(now)
|
|
1249
|
+
// The keyed children leaving in this change, by key, over the ones exiting already.
|
|
1250
|
+
const byKey = new Map(keyedLeavers)
|
|
1251
|
+
Arr.forEach(previous, (placed) => {
|
|
1252
|
+
if (Bool.or(kept.has(placed.el), Bool.not(registry.has(placed.el)))) return
|
|
1253
|
+
UndefinedOr.map(keyOf(placed.el), (key) => byKey.set(key, placed.el))
|
|
1254
|
+
})
|
|
1255
|
+
if (byKey.size === 0) return
|
|
1256
|
+
Arr.forEach(now, (el) => {
|
|
1257
|
+
if (onPage.has(el)) return
|
|
1258
|
+
UndefinedOr.map(keyOf(el), (key) =>
|
|
1259
|
+
UndefinedOr.map(byKey.get(key), (leaver) => {
|
|
1260
|
+
if (leaver === el) return
|
|
1261
|
+
takeovers.set(el, leaver)
|
|
1262
|
+
if (Bool.not(leaverBoxes.has(leaver))) leaverBoxes.set(leaver, boxesOf(leaver))
|
|
1263
|
+
}))
|
|
1264
|
+
})
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
/** Where a leaver and the Wardic elements inside it paint now, in the Root frame: each one on the page. */
|
|
1268
|
+
const boxesOf = (leaver: HTMLElement): ReadonlyMap<Element, Box.Box> => {
|
|
1269
|
+
const boxes = new Map<Element, Box.Box>()
|
|
1270
|
+
Arr.forEach([leaver, ...Arr.map(partsOf(leaver), (part) => part.element)], (el) =>
|
|
1271
|
+
Option.map(projection.rootBoxOf(el), (box) => boxes.set(el, box)))
|
|
1272
|
+
return boxes
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
/** The take-overs found, each done once: at the first of the child's wards' mounts, or the presence's next look. */
|
|
1276
|
+
const settleTakeovers = (): void => {
|
|
1277
|
+
if (takeovers.size === 0) return
|
|
1278
|
+
const due = Arr.fromIterable(takeovers)
|
|
1279
|
+
takeovers.clear()
|
|
1280
|
+
Arr.forEach(due, ([el, leaver]) => takeOver(el, leaver))
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
// Children taken over in the change they left in: they never start an exit.
|
|
1284
|
+
const takenOver = new WeakSet<HTMLElement>()
|
|
1285
|
+
|
|
1286
|
+
/**
|
|
1287
|
+
* `el` takes over from `leaver`: each Wardic element in it starts where the one it pairs with in
|
|
1288
|
+
* the leaver is drawn, the child itself with the leaver, and those inside in document order when
|
|
1289
|
+
* the two have the same shape (as many, each pair the same tag). The leaver goes at once. An exiting
|
|
1290
|
+
* one's exit ends, uncompleted, as an interrupted one's does (Motion tells no completion for a key
|
|
1291
|
+
* back); one leaving in this change never starts its exit, nor are its hooks told it left.
|
|
1292
|
+
*/
|
|
1293
|
+
const takeOver = (el: HTMLElement, leaver: HTMLElement): void => {
|
|
1294
|
+
const from = registry.get(leaver)
|
|
1295
|
+
// Gone since (its exit ended): the child enters as any other.
|
|
1296
|
+
if (Predicate.isUndefined(from)) return
|
|
1297
|
+
const before = partsOf(leaver)
|
|
1298
|
+
const after = madeWithin(el)
|
|
1299
|
+
// Each as drawn, and where it painted: a layout node moves from there (#286's PR 2).
|
|
1300
|
+
const boxes = UndefinedOr.match(leaverBoxes.get(leaver), { onUndefined: (): ReadonlyMap<Element, Box.Box> => NO_BOXES, onDefined: identity })
|
|
1301
|
+
leaverBoxes.delete(leaver)
|
|
1302
|
+
const seedOf = (rec: PresenceRecord): Drawn => ({ ...drawnOf(rec), box: boxes.get(rec.element) })
|
|
1303
|
+
const paired = sameShape(Arr.map(before, (part) => part.element), after)
|
|
1304
|
+
if (paired) Arr.forEach(Arr.zip(before, after), ([part, into]) => seeds.set(into, seedOf(part)))
|
|
1305
|
+
debug("leave: taken over", { parts: before.length, paired })
|
|
1306
|
+
// A twin crossfading out (Q8: D): its leaving Follower goes at once, uncompleted, and the new
|
|
1307
|
+
// node's handover fades on from where it had faded to, as Motion's same element would.
|
|
1308
|
+
if (crossfades.has(leaver)) {
|
|
1309
|
+
leaveEnds(leaver, false)
|
|
1310
|
+
seeds.set(el, { ...seedOf(from), fade: Option.getOrUndefined(projection.dropLeaver(leaver)) })
|
|
1311
|
+
return
|
|
1312
|
+
}
|
|
1313
|
+
seeds.set(el, seedOf(from))
|
|
1314
|
+
// Retained, or its leave waiting for its task's end (#482).
|
|
1315
|
+
if (Bool.or(pending.has(leaver), exiting.has(leaver))) {
|
|
1316
|
+
interruptExit(leaver)
|
|
1317
|
+
return
|
|
1318
|
+
}
|
|
1319
|
+
// Leaving in this change: it goes as Solid took it, its records and hooks with it.
|
|
1320
|
+
takenOver.add(leaver)
|
|
1321
|
+
pops.delete(leaver)
|
|
1322
|
+
Arr.forEach([from, ...before], (rec) => registry.delete(rec.element))
|
|
1323
|
+
Arr.forEach(watchesIn(leaver), (watch) => {
|
|
1324
|
+
watches.delete(watch)
|
|
1325
|
+
watch.gone()
|
|
1326
|
+
})
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
const present = (current: unknown): void => {
|
|
1330
|
+
const now = elementsOf(current)
|
|
1331
|
+
const kept = new Set(now)
|
|
1332
|
+
// A child entering pushes its siblings (#442): not on the page at the last change, the first one
|
|
1333
|
+
// included, so a presence mounting moves a `layout` element after it, as Motion's re-render does.
|
|
1334
|
+
const wasThere = new Set(Arr.map(previous, (placed) => placed.el))
|
|
1335
|
+
const entered = Arr.some(now, (el) => Bool.not(wasThere.has(el)))
|
|
1336
|
+
// The take-overs found as these children went on the page (#286), before any leaves: a child
|
|
1337
|
+
// taken over in the change it left in doesn't leave.
|
|
1338
|
+
if (takeovers.size > 0) {
|
|
1339
|
+
Arr.forEach(Arr.fromIterable(takeovers.keys()), (el) => {
|
|
1340
|
+
if (Bool.not(kept.has(el))) takeovers.delete(el)
|
|
1341
|
+
})
|
|
1342
|
+
settleTakeovers()
|
|
1343
|
+
}
|
|
1344
|
+
// The children that left go back in Motion's order (#486): each right after the staying child it
|
|
1345
|
+
// followed before the change, after the leavers back there already; first, when it followed none.
|
|
1346
|
+
// Leavers from earlier changes, still exiting, keep their places in it.
|
|
1347
|
+
const gone = new Map(Arr.map(Arr.filter(previous, (placed) => Bool.and(Bool.not(kept.has(placed.el)), Bool.not(takenOver.has(placed.el)))), (placed) => [placed.el, placed] as const))
|
|
1348
|
+
const before = Arr.filter(rendered, (el) => Bool.or(Bool.or(kept.has(el), gone.has(el)), Bool.and(el.isConnected, Bool.not(takenOver.has(el)))))
|
|
1349
|
+
const listed = new Set(before)
|
|
1350
|
+
const order = orderOf(Arr.appendAll(before, Arr.filter(Arr.map(previous, (placed) => placed.el), (el) => Bool.not(listed.has(el)))), now)
|
|
1351
|
+
Arr.forEach(order, (el, i) => UndefinedOr.map(gone.get(el), (placed) => left(placed, backPlaceOf(placed, order, i))))
|
|
1352
|
+
rendered = Arr.filter(order, (el) => el.isConnected)
|
|
1353
|
+
// A child still exiting that the framework took out since (a list emptied) goes back too.
|
|
1354
|
+
Arr.forEach(Arr.fromIterable(places.values()), putBack)
|
|
1355
|
+
previous = Arr.map(now, placedOf)
|
|
1356
|
+
// Where its children are (#277's PR 5c): a parent presence finds it inside its leaving child by it.
|
|
1357
|
+
if (now.length > 0) anchor = parentElementOf(previous)
|
|
1358
|
+
// A record whose element left the page some other way (its own control flow, inside a child that
|
|
1359
|
+
// stays) is dropped (#290): nothing exits it, and nothing else would.
|
|
1360
|
+
Arr.forEach(Arr.fromIterable(registry.keys()), dropDetached)
|
|
1361
|
+
Arr.forEach(Arr.fromIterable(watches), dropDetachedWatch)
|
|
1362
|
+
// A popped leaver moved its siblings (#277), and so did a child entering (#442): a `layout` one
|
|
1363
|
+
// animates into the space, as Motion's presence re-renders its children then.
|
|
1364
|
+
if (Bool.and(Bool.or(popped, entered), affectsLayout())) projection.notify()
|
|
1365
|
+
popped = false
|
|
1366
|
+
// The wards inside the children held until now start, the children on the page (#277). Held
|
|
1367
|
+
// children go on together, so none is left held then. (A ward started while its child is held
|
|
1368
|
+
// would only wait again: the check saves its re-run.)
|
|
1369
|
+
if (Bool.and(starts.size > 0, held.length === 0)) startHeld()
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
/** The held wards' starts, each once. */
|
|
1373
|
+
const startHeld = (): void => {
|
|
1374
|
+
const ready = Arr.fromIterable(starts.values())
|
|
1375
|
+
starts.clear()
|
|
1376
|
+
Arr.forEach(ready, (start) => start())
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
/** The presence's `custom` now (#277): `undefined` without one. */
|
|
1380
|
+
const customNow = (): unknown => UndefinedOr.map(options.custom, (custom) => custom())
|
|
1381
|
+
|
|
1382
|
+
/** The mode now: `"sync"` unless the prop says otherwise. */
|
|
1383
|
+
const modeNow = (): PresenceMode | undefined => UndefinedOr.map(options.mode, (mode) => mode())
|
|
1384
|
+
|
|
1385
|
+
/** Whether the projection is told when its children move (#442, `presenceAffectsLayout`): unless the prop says `false`. */
|
|
1386
|
+
const affectsLayout = (): boolean => UndefinedOr.map(options.presenceAffectsLayout, (affects) => affects()) !== false
|
|
1387
|
+
|
|
1388
|
+
/**
|
|
1389
|
+
* Whether an entering child waits (#277): under `mode="wait"`, while a child exits, or one shown at
|
|
1390
|
+
* the last change is leaving now and stays to exit (a Wardic element, or a plain one with something
|
|
1391
|
+
* inside it to wait for, #392).
|
|
1392
|
+
*/
|
|
1393
|
+
const waits = (kept: ReadonlySet<HTMLElement>): boolean =>
|
|
1394
|
+
Bool.or(
|
|
1395
|
+
leaving.size > 0,
|
|
1396
|
+
Arr.some(previous, (placed) => {
|
|
1397
|
+
if (kept.has(placed.el)) return false
|
|
1398
|
+
return retains(placed.el)
|
|
1399
|
+
}),
|
|
1400
|
+
)
|
|
1401
|
+
|
|
1402
|
+
const shown = (resolved: unknown): unknown => {
|
|
1403
|
+
const mode = modeNow()
|
|
1404
|
+
// `popLayout` (#277): each child leaving in this change is measured where it is, before the change
|
|
1405
|
+
// moves it, as Motion's `getSnapshotBeforeUpdate`.
|
|
1406
|
+
if (mode === "popLayout") measureLeavers(resolved)
|
|
1407
|
+
// A child back under the key of one leaving takes over from it (#286): found before the mode
|
|
1408
|
+
// decides what goes on the page, so `wait` doesn't hold it. Nothing is looked up with no key.
|
|
1409
|
+
if (keyed) findTakeovers(resolved)
|
|
1410
|
+
if (mode !== "wait") {
|
|
1411
|
+
held = []
|
|
1412
|
+
return resolved
|
|
1413
|
+
}
|
|
1414
|
+
const now = elementsOf(resolved)
|
|
1415
|
+
const kept = new Set(now)
|
|
1416
|
+
// Entering: not on the page at the last change.
|
|
1417
|
+
const onPage = new Set(Arr.map(previous, (placed) => placed.el))
|
|
1418
|
+
held = Bool.match(waits(kept), { onTrue: () => Arr.filter(now, (el) => Bool.and(Bool.not(onPage.has(el)), Bool.not(takeovers.has(el)))), onFalse: () => [] })
|
|
1419
|
+
if (held.length === 0) return resolved
|
|
1420
|
+
const holding = new Set<unknown>(held)
|
|
1421
|
+
return Arr.filter(Arr.ensure(resolved), (node) => Bool.not(holding.has(node)))
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
const leaveAll = (done: () => void): void => {
|
|
1425
|
+
onAllLeft = done
|
|
1426
|
+
present([])
|
|
1427
|
+
if (leaving.size === 0) allLeft()
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
return {
|
|
1431
|
+
context: ctx,
|
|
1432
|
+
shown,
|
|
1433
|
+
leaveAll,
|
|
1434
|
+
anchor: () => anchor,
|
|
1435
|
+
mounted: () => {
|
|
1436
|
+
firstRender = false
|
|
1437
|
+
},
|
|
1438
|
+
present,
|
|
1439
|
+
teardown,
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
/**
|
|
1444
|
+
* `propagate` (#277's PR 5c, ADR-0048, Motion's): a presence inside another's child registers with
|
|
1445
|
+
* that one as a hook that holds it. When the child leaves, every child of this presence leaves, and
|
|
1446
|
+
* the parent's child goes once they've all gone. Its own disposal comes first (Solid disposes the
|
|
1447
|
+
* leaving child before its presence hears of it), so its teardown waits a microtask for that word.
|
|
1448
|
+
* Without `propagate`, or a presence above, its teardown runs at its disposal, as before. Returns
|
|
1449
|
+
* what its disposal runs.
|
|
1450
|
+
*/
|
|
1451
|
+
export const propagateTo = (parent: PresenceContextValue | undefined, propagate: boolean, presence: PresenceController): (() => void) => {
|
|
1452
|
+
let torn = false
|
|
1453
|
+
const tear = (): void => {
|
|
1454
|
+
if (torn) return
|
|
1455
|
+
torn = true
|
|
1456
|
+
presence.teardown()
|
|
1457
|
+
}
|
|
1458
|
+
const watch = UndefinedOr.map(parent, (above) => above.watch)
|
|
1459
|
+
if (Bool.or(Bool.not(propagate), Predicate.isUndefined(watch))) return tear
|
|
1460
|
+
let disposed = false
|
|
1461
|
+
let leaving = false
|
|
1462
|
+
;(watch as (watch: PresenceWatch) => void)({
|
|
1463
|
+
element: presence.anchor,
|
|
1464
|
+
holds: true,
|
|
1465
|
+
leave: (_custom, release) => {
|
|
1466
|
+
leaving = true
|
|
1467
|
+
presence.leaveAll(() => {
|
|
1468
|
+
release()
|
|
1469
|
+
tear()
|
|
1470
|
+
})
|
|
1471
|
+
},
|
|
1472
|
+
gone: () => {
|
|
1473
|
+
if (disposed) tear()
|
|
1474
|
+
},
|
|
1475
|
+
})
|
|
1476
|
+
return () => {
|
|
1477
|
+
disposed = true
|
|
1478
|
+
queueMicrotask(() => {
|
|
1479
|
+
if (Bool.not(leaving)) tear()
|
|
1480
|
+
})
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
|