@jsenv/navi 0.29.188 → 0.29.189
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/dist/dev/jsenv_navi.js +1 -1
- package/dist/jsenv_navi.js +1 -1
- package/docs/AI_INSTRUCTIONS.md +5 -0
- package/docs/interactions.md +67 -0
- package/package.json +2 -2
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { installImportMetaCssBuild, windowHeightSignal, windowWidthSignal, visualViewportHeightSignal, visualViewportWidthSignal, getAppHeight, getAppWidth, coarsePointerSignal, smallTouchScreenSignal } from "./jsenv_navi_side_effects.js";
|
|
6
6
|
export { disableVirtualKeyboardOverlay } from "./jsenv_navi_side_effects.js";
|
|
7
7
|
import { elementIsFocusable, createIterableWeakSet, dispatchInternalCustomEvent, dispatchCustomEvent, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, getElementSignature, createPubSub, findEvent, createValueEffect, findFocusDelegateTarget, findFocusable, scrollIntoViewThroughScrollables, allowWheelThrough, dispatchPublicCustomEvent, resolveCSSColor, ELEMENT_SIZE_CHANGE, findSelfOrAncestorFixedPosition, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, applyNewPosition, measureLongestVisualLineWidth, chainEvent, keepTouchRefusable, waitForPressHeld, suppressClickAfterGesture, startDragToTravel, markDragSource, startDragTo, createEventGroupLogger, getKeyboardEventDefaultAction, activeElementSignal, normalizeStyle, mergeOneStyle, getPositionedParent, normalizeStyles, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, watchWheelTravel, scrollRoomTowards, getScrollContainer, closestOpenableAncestor, isAncestorOpen, isDisplayedDespiteClosedAncestor, observeAncestorOpenState, getAncestorOpenType, findBefore, findAfter, resolveCSSSize, hasCSSSizeUnit, releaseWheelGesture, getScrollIntoViewScopedOffsets, wheelGestureIsTakenFrom, claimWheelGesture, scrollIntoViewScoped, initFocusGroup, isTouchDrivenEvent, stringifyStyle as stringifyStyle$1, resolveOklchLightness, contrastColor, parsePositionArea, snapToPixel, trapFocusInside, trapScrollInside, onAncestorReopen, isPressDisputedByDrag, canScroll, measureWidestChildRow, performTabNavigation, dragAfterIntent, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement } from "@jsenv/dom";
|
|
8
|
-
export { chainEvent, clickIsSuppressed, contrastColor, findEvent, startDragTo } from "@jsenv/dom";
|
|
8
|
+
export { chainEvent, clickIsSuppressed, contrastColor, createDragGestureController, dragAfterIntent, findEvent, markDragSource, startDragTo } from "@jsenv/dom";
|
|
9
9
|
import { signal, computed, effect, untracked, batch, useComputed, useSignal } from "@preact/signals";
|
|
10
10
|
import { isValidElement, createContext, render, h, toChildArray, options, cloneElement, Fragment as Fragment$1 } from "preact";
|
|
11
11
|
import { useErrorBoundary, useLayoutEffect, useContext, useCallback, useRef, useState, useEffect, useMemo, useId } from "preact/hooks";
|
package/dist/jsenv_navi.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { installImportMetaCssBuild, windowHeightSignal, windowWidthSignal, visualViewportHeightSignal, visualViewportWidthSignal, getAppHeight, getAppWidth, coarsePointerSignal, smallTouchScreenSignal } from "./jsenv_navi_side_effects.js";
|
|
6
6
|
export { disableVirtualKeyboardOverlay } from "./jsenv_navi_side_effects.js";
|
|
7
7
|
import { elementIsFocusable, createIterableWeakSet, dispatchInternalCustomEvent, dispatchCustomEvent, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, getElementSignature, createPubSub, findEvent, createValueEffect, findFocusDelegateTarget, findFocusable, scrollIntoViewThroughScrollables, allowWheelThrough, dispatchPublicCustomEvent, resolveCSSColor, ELEMENT_SIZE_CHANGE, findSelfOrAncestorFixedPosition, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, applyNewPosition, measureLongestVisualLineWidth, chainEvent, keepTouchRefusable, waitForPressHeld, suppressClickAfterGesture, startDragToTravel, markDragSource, startDragTo, createEventGroupLogger, getKeyboardEventDefaultAction, activeElementSignal, normalizeStyle, mergeOneStyle, getPositionedParent, normalizeStyles, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, watchWheelTravel, scrollRoomTowards, getScrollContainer, closestOpenableAncestor, isAncestorOpen, isDisplayedDespiteClosedAncestor, observeAncestorOpenState, getAncestorOpenType, findBefore, findAfter, resolveCSSSize, hasCSSSizeUnit, releaseWheelGesture, getScrollIntoViewScopedOffsets, wheelGestureIsTakenFrom, claimWheelGesture, scrollIntoViewScoped, initFocusGroup, isTouchDrivenEvent, stringifyStyle as stringifyStyle$1, resolveOklchLightness, contrastColor, parsePositionArea, snapToPixel, trapFocusInside, trapScrollInside, onAncestorReopen, isPressDisputedByDrag, canScroll, measureWidestChildRow, performTabNavigation, dragAfterIntent, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement } from "@jsenv/dom";
|
|
8
|
-
export { chainEvent, clickIsSuppressed, contrastColor, findEvent, startDragTo } from "@jsenv/dom";
|
|
8
|
+
export { chainEvent, clickIsSuppressed, contrastColor, createDragGestureController, dragAfterIntent, findEvent, markDragSource, startDragTo } from "@jsenv/dom";
|
|
9
9
|
import { signal, computed, effect, untracked, batch, useComputed, useSignal } from "@preact/signals";
|
|
10
10
|
import { isValidElement, createContext, render, h, toChildArray, options, cloneElement, Fragment as Fragment$1 } from "preact";
|
|
11
11
|
import { useErrorBoundary, useLayoutEffect, useContext, useCallback, useRef, useState, useEffect, useMemo, useId } from "preact/hooks";
|
package/docs/AI_INSTRUCTIONS.md
CHANGED
|
@@ -328,6 +328,11 @@ consistency across the app, not from any single call site.
|
|
|
328
328
|
NOT stop (a plain `onClick` on an ancestor). It also draws the line with
|
|
329
329
|
`standalone`: those two answer about the GESTURE, `standalone` about the
|
|
330
330
|
VALUE, and they are three separate props because they come apart.
|
|
331
|
+
And it says what happens when the gesture's product is a VALUE — an angle, a
|
|
332
|
+
scale, a plan panned under the finger — rather than an element that ends up
|
|
333
|
+
somewhere: no interaction names that, so navi hands over the machinery
|
|
334
|
+
(`createDragGestureController`, `dragAfterIntent`, `markDragSource`, all
|
|
335
|
+
re-exported from navi) with the three traps it takes care of.
|
|
331
336
|
Read it before reading the pointer by hand — who owns a press between nested
|
|
332
337
|
boxes, and what a touch may do, are decided before the first pixel moves and
|
|
333
338
|
cannot be got right from outside navi — and before stopping the propagation of
|
package/docs/interactions.md
CHANGED
|
@@ -781,6 +781,70 @@ container above it does not take the gesture:
|
|
|
781
781
|
`docs/drag_to_travel.md`). navi's own swipes do the equivalent with
|
|
782
782
|
`data-travel-by-drag`.
|
|
783
783
|
|
|
784
|
+
## A gesture whose product is a value
|
|
785
|
+
|
|
786
|
+
`move`, `reorder`, `land` and `toss` answer the same question — where did the
|
|
787
|
+
element end up — because all four carry it. A rotation does not: what comes out of
|
|
788
|
+
it is an angle, and the handle that produced it stays exactly where it is. Same for
|
|
789
|
+
a scale, a zoom, a plan panned under the finger.
|
|
790
|
+
|
|
791
|
+
navi names none of those, and it is not an oversight: an interaction names an
|
|
792
|
+
**outcome** — something that happened once, that can be told, refused, awaited.
|
|
793
|
+
There is no outcome here, only a number read while the hand is still moving, and
|
|
794
|
+
what to do with it (snap it to the neighbouring court, draw it, keep it in a
|
|
795
|
+
signal) is knowledge navi does not have. So it hands over the machinery instead
|
|
796
|
+
and leaves the paint alone:
|
|
797
|
+
|
|
798
|
+
```js
|
|
799
|
+
import { createDragGestureController, dragAfterIntent } from "@jsenv/navi";
|
|
800
|
+
|
|
801
|
+
const onPointerDown = (pointerDownEvent) => {
|
|
802
|
+
dragAfterIntent(pointerDownEvent, () => {
|
|
803
|
+
const controller = createDragGestureController({
|
|
804
|
+
onDrag: (gestureInfo) => {
|
|
805
|
+
const { xDelta, yDelta } = gestureInfo.layout;
|
|
806
|
+
angleSignal.value = snapToNeighbours(angleFromDelta(xDelta, yDelta));
|
|
807
|
+
},
|
|
808
|
+
onRelease: (gestureInfo) => {
|
|
809
|
+
if (gestureInfo.cancelled) {
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
COURT.PUT.run({ angle: angleSignal.peek() });
|
|
813
|
+
},
|
|
814
|
+
});
|
|
815
|
+
return controller.grabViaPointer(pointerDownEvent, {
|
|
816
|
+
element: pointerDownEvent.currentTarget,
|
|
817
|
+
});
|
|
818
|
+
});
|
|
819
|
+
};
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
An element that ends up somewhere is NOT this: that one is `move`, and doing it by
|
|
823
|
+
hand gives up the constraint, the commit and the way back when the answer refuses.
|
|
824
|
+
|
|
825
|
+
Three things come with the machinery, and they are the reason not to write it again:
|
|
826
|
+
|
|
827
|
+
- **When the press becomes a drag** is `dragAfterIntent`, and the answer is not one
|
|
828
|
+
policy but three: a `data-drag-handle` exists only to drag, so it takes the
|
|
829
|
+
gesture on contact; a mouse resolves it by distance; a finger resolves it by
|
|
830
|
+
TIME, because travel is exactly what a scroll looks like. One timer for every
|
|
831
|
+
pointer makes the mouse wait for something it never had to prove.
|
|
832
|
+
- **A touch has to be refusable before it is refused.** `touch-action` must be
|
|
833
|
+
non-`auto` when the finger LANDS: after that the touch is on the compositor's
|
|
834
|
+
fast path, every `preventDefault` is an intervention, and on Android the scroll
|
|
835
|
+
runs away with the object. `markDragSource(element, axes)` says it from a
|
|
836
|
+
stylesheet, on the source itself — which is how what surrounds it keeps
|
|
837
|
+
scrolling. A blanket `touch-action: none` on the container buys the same drag by
|
|
838
|
+
taking the pan away, and the pan then has to be written by hand too.
|
|
839
|
+
- **A capture that goes was not necessarily given back.** `lostpointercapture`
|
|
840
|
+
reads the same whether the gesture handed the pointer over or the browser dropped
|
|
841
|
+
it mid-drag, which it does more often than the specification suggests. The loop
|
|
842
|
+
tells the two apart, and `gestureInfo.cancelled` is where it comes out: a release
|
|
843
|
+
nobody asked for must commit nothing.
|
|
844
|
+
|
|
845
|
+
A gesture driven this way is outside the registry, so it says so itself to whatever
|
|
846
|
+
travels above it: `data-no-drag-travel` (see `docs/drag_to_travel.md`).
|
|
847
|
+
|
|
784
848
|
## Things worth knowing before guessing
|
|
785
849
|
|
|
786
850
|
- **A drag says its axes to whoever else answers the press.** `data-drag-axis`
|
|
@@ -834,6 +898,9 @@ container above it does not take the gesture:
|
|
|
834
898
|
`toss` and the `grab` moment.
|
|
835
899
|
- `src/control/interaction/interaction_keyboard.js`,
|
|
836
900
|
`interaction_native.js` — the other two detectors.
|
|
901
|
+
- `@jsenv/dom` — `src/interaction/drag/drag_gesture.js` (the loop, its options and
|
|
902
|
+
what `gestureInfo` holds) and `src/interaction/drag/drag_after_intent.js` (when a
|
|
903
|
+
press becomes a drag, and what a source says in the stylesheet).
|
|
837
904
|
- `src/control/demos/38_interactions_demo.html` — every case above, plus a
|
|
838
905
|
mailbox, a board whose places are zones and the same board whose places are the
|
|
839
906
|
pieces, and a custom gesture registered from the page.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/navi",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.189",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Library of components including navigation to create frontend applications",
|
|
6
6
|
"repository": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"prepublishOnly": "npm run build"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@jsenv/dom": "0.17.
|
|
37
|
+
"@jsenv/dom": "0.17.45",
|
|
38
38
|
"@jsenv/humanize": "1.7.8",
|
|
39
39
|
"@jsenv/validity": "0.4.3"
|
|
40
40
|
},
|