@jsenv/navi 0.29.323 → 0.29.325
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/README.md +2 -0
- package/dist/dev/jsenv_navi.js +312 -244
- package/dist/dev/jsenv_navi.js.map +22 -22
- package/dist/jsenv_navi.js +279 -244
- package/dist/jsenv_navi.js.map +22 -22
- package/docs/AI_INSTRUCTIONS.md +6 -3
- package/docs/dialog_shape.md +38 -18
- package/docs/drag_to_travel.md +3 -3
- package/docs/popup_backdrop.md +39 -6
- package/docs/popup_open.md +67 -0
- package/package.json +2 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
*/
|
|
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
|
-
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, isPressDrivenClick, waitForTap, waitForPressHeld, suppressClickAfterGesture, startDragToTravel, dragSourceThatStoodDown, markDragSource, refuseDragTo, startDragTo, installPanZoom, getKeyboardEventDefaultAction, activeElementSignal, normalizeStyle, mergeOneStyle, getPositionedParent, normalizeStyles, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, watchWheelTravel, scrollRoomTowards, getScrollContainer, isTouchDrivenEvent, scrollIntoViewScoped, closestOpenableAncestor, isAncestorOpen, isDisplayedDespiteClosedAncestor, observeAncestorOpenState, getAncestorOpenType, findBefore, findAfter, resolveCSSSize, hasCSSSizeUnit, releaseWheelGesture, getScrollIntoViewScopedOffsets, wheelGestureIsTakenFrom, claimWheelGesture, initFocusGroup, stringifyStyle as stringifyStyle$1, resolveOklchLightness, contrastColor, parsePositionArea, snapToPixel, trapFocusInside, trapScrollInside, onAncestorReopen, isPressDisputedByDrag, canScroll, measureWidestChildRow, performTabNavigation, dragAfterIntent, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement } from "@jsenv/dom";
|
|
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, isPressDrivenClick, waitForTap, waitForPressHeld, suppressClickAfterGesture, startDragToTravel, dragSourceThatStoodDown, markDragSource, refuseDragTo, startDragTo, installPanZoom, createInternalCustomEvent, getKeyboardEventDefaultAction, activeElementSignal, normalizeStyle, mergeOneStyle, getPositionedParent, normalizeStyles, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, watchWheelTravel, scrollRoomTowards, getScrollContainer, isTouchDrivenEvent, scrollIntoViewScoped, closestOpenableAncestor, isAncestorOpen, isDisplayedDespiteClosedAncestor, observeAncestorOpenState, getAncestorOpenType, findBefore, findAfter, resolveCSSSize, hasCSSSizeUnit, releaseWheelGesture, getScrollIntoViewScopedOffsets, wheelGestureIsTakenFrom, claimWheelGesture, initFocusGroup, 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
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
|
-
import { isValidElement, createContext, render, h, toChildArray, options, cloneElement, Fragment as Fragment$1 } from "preact";
|
|
10
|
+
import { isValidElement, createContext, render, h, toChildArray, options, cloneElement, createElement, Fragment as Fragment$1 } from "preact";
|
|
11
11
|
import { useErrorBoundary, useLayoutEffect, useContext, useCallback, useRef, useState, useEffect, useMemo, useId } from "preact/hooks";
|
|
12
12
|
import { humanizeI18n, setRuntimeLangSource, formatDuration, formatMonth, formatDay, resolveTimeRangePrecision, formatDatePlaceholder, toDate, getRelativeDay, formatDayRelative, formatMonthPlaceholder, formatWeekPlaceholder, formatDatetimePlaceholder, formatDatetime, toTimeOfDay, formatTimeOfDay, formatTime, formatMinuteDuration, formatSecondDuration, formatHourDuration, formatTimeRelative, formatNumber, interpolateText, installInterpolateJsx } from "@jsenv/humanize";
|
|
13
13
|
export { createI18n, formatDatetime, formatDay, formatDayRelative, formatDuration, formatHourDuration, formatMinuteDuration, formatMonth, formatNumber, formatSecondDuration, formatTime, formatTimeOfDay, formatTimeRange, formatTimeRelative, interpolateText } from "@jsenv/humanize";
|
|
@@ -12616,6 +12616,12 @@ const useExecuteAction = (
|
|
|
12616
12616
|
// whose command sent — is stored as the callout display target, so the
|
|
12617
12617
|
// message appears on whoever asked rather than on the whole control.
|
|
12618
12618
|
const element = elementRef.current;
|
|
12619
|
+
if (!element) {
|
|
12620
|
+
// The control left the page while its run was out (its own answer can
|
|
12621
|
+
// unmount it, see the outcome events below): there is no box to hang
|
|
12622
|
+
// the refusal on. onActionError is still told, by the run's side effect.
|
|
12623
|
+
return;
|
|
12624
|
+
}
|
|
12619
12625
|
let target = requester;
|
|
12620
12626
|
// A requester that is no longer on the page is not a place to show
|
|
12621
12627
|
// anything: the clear cross leaves with the value it optimistically
|
|
@@ -12718,12 +12724,20 @@ const useExecuteAction = (
|
|
|
12718
12724
|
// Either three callbacks, one per outcome, or a single one for "however
|
|
12719
12725
|
// this ends" — it receives `{ aborted, reason }`, `{ error }` or
|
|
12720
12726
|
// `{ data }`, so a caller that only needs to know the action settled
|
|
12721
|
-
// (and whether it worked) does not have to register three.
|
|
12727
|
+
// (and whether it worked) does not have to register three. Each also
|
|
12728
|
+
// receives the outcome event (navi_action_abort/error/end) as its
|
|
12729
|
+
// second argument.
|
|
12722
12730
|
const addSideEffect = (sideEffect) => {
|
|
12723
12731
|
if (typeof sideEffect === "function") {
|
|
12724
|
-
addAbortCallback((reason) =>
|
|
12725
|
-
|
|
12726
|
-
|
|
12732
|
+
addAbortCallback((reason, outcomeEvent) =>
|
|
12733
|
+
sideEffect({ aborted: true, reason }, outcomeEvent),
|
|
12734
|
+
);
|
|
12735
|
+
addErrorCallback((error, outcomeEvent) =>
|
|
12736
|
+
sideEffect({ error }, outcomeEvent),
|
|
12737
|
+
);
|
|
12738
|
+
addCompleteCallback((data, outcomeEvent) =>
|
|
12739
|
+
sideEffect({ data }, outcomeEvent),
|
|
12740
|
+
);
|
|
12727
12741
|
return;
|
|
12728
12742
|
}
|
|
12729
12743
|
const { abort, error, complete } = sideEffect;
|
|
@@ -12731,56 +12745,6 @@ const useExecuteAction = (
|
|
|
12731
12745
|
addErrorCallback(error);
|
|
12732
12746
|
addCompleteCallback(complete);
|
|
12733
12747
|
};
|
|
12734
|
-
addSideEffect({
|
|
12735
|
-
abort: (reason) => {
|
|
12736
|
-
const element = elementRef.current;
|
|
12737
|
-
if (
|
|
12738
|
-
// at this stage the action side effect might have removed the <element> from the DOM
|
|
12739
|
-
// (in theory no because action side effect are batched to happen after)
|
|
12740
|
-
// but other side effects might do this
|
|
12741
|
-
element
|
|
12742
|
-
) {
|
|
12743
|
-
dispatchInternalCustomEvent(element, "navi_action_abort", {
|
|
12744
|
-
...sharedActionEventDetail,
|
|
12745
|
-
reason,
|
|
12746
|
-
});
|
|
12747
|
-
}
|
|
12748
|
-
},
|
|
12749
|
-
error: (error) => {
|
|
12750
|
-
if (errorEffect === "show_validation_message") {
|
|
12751
|
-
addErrorMessage(error, { requester });
|
|
12752
|
-
} else if (errorEffect === "throw") {
|
|
12753
|
-
setError(error);
|
|
12754
|
-
}
|
|
12755
|
-
|
|
12756
|
-
const element = elementRef.current;
|
|
12757
|
-
if (
|
|
12758
|
-
// at this stage the action side effect might have removed the <element> from the DOM
|
|
12759
|
-
// (in theory no because action side effect are batched to happen after)
|
|
12760
|
-
// but other side effects might do this
|
|
12761
|
-
element
|
|
12762
|
-
) {
|
|
12763
|
-
dispatchInternalCustomEvent(element, "navi_action_error", {
|
|
12764
|
-
...sharedActionEventDetail,
|
|
12765
|
-
error,
|
|
12766
|
-
});
|
|
12767
|
-
}
|
|
12768
|
-
},
|
|
12769
|
-
complete: (data) => {
|
|
12770
|
-
const element = elementRef.current;
|
|
12771
|
-
if (
|
|
12772
|
-
// at this stage the action side effect might have removed the <element> from the DOM
|
|
12773
|
-
// (in theory no because action side effect are batched to happen after)
|
|
12774
|
-
// but other side effects might do this
|
|
12775
|
-
element
|
|
12776
|
-
) {
|
|
12777
|
-
dispatchInternalCustomEvent(element, "navi_action_end", {
|
|
12778
|
-
...sharedActionEventDetail,
|
|
12779
|
-
data,
|
|
12780
|
-
});
|
|
12781
|
-
}
|
|
12782
|
-
},
|
|
12783
|
-
});
|
|
12784
12748
|
|
|
12785
12749
|
const actionStartEventDetail = {
|
|
12786
12750
|
...sharedActionEventDetail,
|
|
@@ -12792,13 +12756,50 @@ const useExecuteAction = (
|
|
|
12792
12756
|
actionStartEventDetail,
|
|
12793
12757
|
);
|
|
12794
12758
|
|
|
12759
|
+
// The outcome is told twice: to the element, when there still is one,
|
|
12760
|
+
// and to the side effects registered at navi_action_start, always. A
|
|
12761
|
+
// run can outlive its control — the run's own answer, written to a
|
|
12762
|
+
// store the parent reads to decide what it draws, unmounts the control
|
|
12763
|
+
// one microtask before the run settles — and the element is then no
|
|
12764
|
+
// place to dispatch to: Preact drops a detached element's listeners.
|
|
12765
|
+
// The side effects are the run's, not the element's, so the event
|
|
12766
|
+
// reaches them either way.
|
|
12767
|
+
const tellOutcome = (outcomeEventName, outcomeEventDetail, trigger) => {
|
|
12768
|
+
const outcomeEvent = createInternalCustomEvent(outcomeEventName, {
|
|
12769
|
+
...sharedActionEventDetail,
|
|
12770
|
+
...outcomeEventDetail,
|
|
12771
|
+
});
|
|
12772
|
+
const element = elementRef.current;
|
|
12773
|
+
if (element) {
|
|
12774
|
+
element.dispatchEvent(outcomeEvent);
|
|
12775
|
+
}
|
|
12776
|
+
trigger(outcomeEvent);
|
|
12777
|
+
};
|
|
12778
|
+
|
|
12795
12779
|
const runAction = () => {
|
|
12796
12780
|
return action[method]({
|
|
12797
12781
|
event: actionEvent,
|
|
12798
12782
|
reason: `"${event.type}" event on ${getElementSignature(event.target)}`,
|
|
12799
|
-
onAbort:
|
|
12800
|
-
|
|
12801
|
-
|
|
12783
|
+
onAbort: (reason) => {
|
|
12784
|
+
tellOutcome("navi_action_abort", { reason }, (outcomeEvent) => {
|
|
12785
|
+
triggerAbort(reason, outcomeEvent);
|
|
12786
|
+
});
|
|
12787
|
+
},
|
|
12788
|
+
onError: (error) => {
|
|
12789
|
+
if (errorEffect === "show_validation_message") {
|
|
12790
|
+
addErrorMessage(error, { requester });
|
|
12791
|
+
} else if (errorEffect === "throw") {
|
|
12792
|
+
setError(error);
|
|
12793
|
+
}
|
|
12794
|
+
tellOutcome("navi_action_error", { error }, (outcomeEvent) => {
|
|
12795
|
+
triggerError(error, outcomeEvent);
|
|
12796
|
+
});
|
|
12797
|
+
},
|
|
12798
|
+
onComplete: (data) => {
|
|
12799
|
+
tellOutcome("navi_action_end", { data }, (outcomeEvent) => {
|
|
12800
|
+
triggerComplete(data, outcomeEvent);
|
|
12801
|
+
});
|
|
12802
|
+
},
|
|
12802
12803
|
});
|
|
12803
12804
|
};
|
|
12804
12805
|
|
|
@@ -31648,8 +31649,26 @@ const resolveExplicitTarget = (element) => {
|
|
|
31648
31649
|
}
|
|
31649
31650
|
return undefined;
|
|
31650
31651
|
};
|
|
31652
|
+
// The control around the source that a command can be about: one holding a
|
|
31653
|
+
// value of its own. A popup is a control root too (it answers interactions,
|
|
31654
|
+
// carries a callout), but it has no host of its own — asked for one, it
|
|
31655
|
+
// answers with the first control INSIDE it, which for a field sending
|
|
31656
|
+
// --navi-update from a picker's popup is that very field: the command then
|
|
31657
|
+
// sets the field to what it already holds, which fires the command again,
|
|
31658
|
+
// without end. Such a surface is walked past, up to the picker or the form.
|
|
31651
31659
|
const resolveFirstParentControl = (el) => {
|
|
31652
|
-
|
|
31660
|
+
let parentControl = getParentControl(el);
|
|
31661
|
+
while (parentControl && !ownsControlHost(parentControl)) {
|
|
31662
|
+
parentControl = getParentControl(parentControl);
|
|
31663
|
+
}
|
|
31664
|
+
return parentControl;
|
|
31665
|
+
};
|
|
31666
|
+
const ownsControlHost = (controlRoot) => {
|
|
31667
|
+
const controlHost = findControlHost(controlRoot);
|
|
31668
|
+
return (
|
|
31669
|
+
Boolean(controlHost) &&
|
|
31670
|
+
controlHost.closest("[navi-control]") === controlRoot
|
|
31671
|
+
);
|
|
31653
31672
|
};
|
|
31654
31673
|
const resolveFirstChildControl = (el) => {
|
|
31655
31674
|
let startEl;
|
|
@@ -34400,6 +34419,21 @@ const resolveAutoAnimationKind = (anchor, parsedPositionArea) => {
|
|
|
34400
34419
|
*/
|
|
34401
34420
|
const OUTSIDE_REGION_ATTRIBUTE = "data-navi-popup-outside";
|
|
34402
34421
|
|
|
34422
|
+
/**
|
|
34423
|
+
* `data-navi-popup-inside` is the other direction: a box of the PAGE the
|
|
34424
|
+
* caller says belongs to a popup, so a press on it is not outside that popup
|
|
34425
|
+
* even though it lies beyond the border box — a card whose press is what
|
|
34426
|
+
* fills the one panel of a board. Its value names the popup by `id`, the way
|
|
34427
|
+
* `commandfor` does (several ids, space separated), because the exemption is
|
|
34428
|
+
* one popup's: a menu open beside the board still closes on the same press.
|
|
34429
|
+
*
|
|
34430
|
+
* Unlike the outside marker it answers for its whole subtree: the outside
|
|
34431
|
+
* marker carves free space out of a surface whose controls stay surface, this
|
|
34432
|
+
* one adds a whole thing — the card, its count, its buttons — to the popup's
|
|
34433
|
+
* own ground, and nothing in it is a dismissal.
|
|
34434
|
+
*/
|
|
34435
|
+
const INSIDE_ATTRIBUTE = "data-navi-popup-inside";
|
|
34436
|
+
|
|
34403
34437
|
/**
|
|
34404
34438
|
* What a press landing on a region the caller declared as not-its-surface
|
|
34405
34439
|
* does: exactly what the same press on the backdrop would do.
|
|
@@ -34524,6 +34558,14 @@ const armOutsidePressClose = (
|
|
|
34524
34558
|
) {
|
|
34525
34559
|
return;
|
|
34526
34560
|
}
|
|
34561
|
+
if (
|
|
34562
|
+
popupEl.id &&
|
|
34563
|
+
pointerDownEvent.target.closest?.(
|
|
34564
|
+
`[${INSIDE_ATTRIBUTE}~="${CSS.escape(popupEl.id)}"]`,
|
|
34565
|
+
)
|
|
34566
|
+
) {
|
|
34567
|
+
return;
|
|
34568
|
+
}
|
|
34527
34569
|
// Real DOM containment wins over the rectangle below — an element
|
|
34528
34570
|
// genuinely inside the popup (`overflow: visible`, a negative margin, an
|
|
34529
34571
|
// absolutely-positioned child) can be painted outside its border box, and
|
|
@@ -39827,10 +39869,24 @@ const useInteractiveProps = (props, {
|
|
|
39827
39869
|
// aborted run, whose promise is awaited to completion (see
|
|
39828
39870
|
// performRun in actions.js) — which is exactly what "the server is
|
|
39829
39871
|
// done with it" means, and therefore when the queued request may go.
|
|
39830
|
-
e.detail.addSideEffect(outcome => {
|
|
39872
|
+
e.detail.addSideEffect((outcome, outcomeEvent) => {
|
|
39831
39873
|
uiStateController.actionInFlight = false;
|
|
39832
39874
|
uiStateController.runningActionSignal.value = null;
|
|
39833
39875
|
uiStateController.parallelGuard?.release(uiStateController);
|
|
39876
|
+
// The outcome callbacks are told from here, the run's side effect,
|
|
39877
|
+
// and not from the onnavi_action_* handlers below: the run can
|
|
39878
|
+
// outlive this control (its own answer, written to a store the
|
|
39879
|
+
// parent reads, unmounts it one microtask before it settles), and
|
|
39880
|
+
// whoever wears the run — a parent's `loading` following these,
|
|
39881
|
+
// see 12_picker_card_demo.html — must hear it end all the same.
|
|
39882
|
+
// The handlers below keep what needs the element.
|
|
39883
|
+
if (outcome.aborted) {
|
|
39884
|
+
onActionAborted?.(outcomeEvent);
|
|
39885
|
+
} else if ("error" in outcome) {
|
|
39886
|
+
onActionError?.(outcome.error, outcomeEvent);
|
|
39887
|
+
} else {
|
|
39888
|
+
onActionEnd?.(outcome.data, outcomeEvent);
|
|
39889
|
+
}
|
|
39834
39890
|
const queuedEvent = uiStateController.queuedActionAllowedEvent;
|
|
39835
39891
|
if (!queuedEvent) {
|
|
39836
39892
|
syncOptimisticAttribute(false);
|
|
@@ -39870,7 +39926,6 @@ const useInteractiveProps = (props, {
|
|
|
39870
39926
|
if (resetOnAbort && !superseded) {
|
|
39871
39927
|
dispatchRequestResetUIState(e.currentTarget, e);
|
|
39872
39928
|
}
|
|
39873
|
-
onActionAborted?.(e);
|
|
39874
39929
|
},
|
|
39875
39930
|
onnavi_action_error: e => {
|
|
39876
39931
|
const {
|
|
@@ -39879,7 +39934,6 @@ const useInteractiveProps = (props, {
|
|
|
39879
39934
|
if (resetOnError) {
|
|
39880
39935
|
dispatchRequestResetUIState(e.currentTarget, e);
|
|
39881
39936
|
}
|
|
39882
|
-
onActionError?.(error, e);
|
|
39883
39937
|
uiStateController.onActionError(e);
|
|
39884
39938
|
},
|
|
39885
39939
|
onnavi_action_end: e => {
|
|
@@ -39887,7 +39941,6 @@ const useInteractiveProps = (props, {
|
|
|
39887
39941
|
data
|
|
39888
39942
|
} = e.detail;
|
|
39889
39943
|
debugAction(e, `action end with data: ${JSON.stringify(data)}`);
|
|
39890
|
-
onActionEnd?.(data, e);
|
|
39891
39944
|
controlRootProps.onnavi_action_end?.(e);
|
|
39892
39945
|
uiStateController.onActionEnd(e);
|
|
39893
39946
|
|
|
@@ -47792,33 +47845,6 @@ const createToggleEvent = open => {
|
|
|
47792
47845
|
return toggleEvent;
|
|
47793
47846
|
};
|
|
47794
47847
|
|
|
47795
|
-
const NextResolverContext = createContext(null);
|
|
47796
|
-
const useNextResolver = () => useContext(NextResolverContext);
|
|
47797
|
-
|
|
47798
|
-
/**
|
|
47799
|
-
* Creates a renderComponent function that passes props through a chain of resolvers.
|
|
47800
|
-
* Each resolver is a Preact component rendered in sequence (hooks are allowed).
|
|
47801
|
-
* To pass through to the next resolver, call useNextResolver() and render the
|
|
47802
|
-
* returned Next component with the desired props.
|
|
47803
|
-
* To terminate the chain early (e.g. render a specialized component), render
|
|
47804
|
-
* directly without calling Next.
|
|
47805
|
-
*
|
|
47806
|
-
* The last entry in the array is the final/target component — it receives null
|
|
47807
|
-
* from useNextResolver() indicating it is terminal.
|
|
47808
|
-
*
|
|
47809
|
-
* Usage:
|
|
47810
|
-
* const renderButton = createComponentResolver([ResolverA, ResolverB, ButtonTarget]);
|
|
47811
|
-
* // Then inside a component render:
|
|
47812
|
-
* renderButton(props)
|
|
47813
|
-
*
|
|
47814
|
-
* Each position of the chain has a runner of its own, defined once: it renders
|
|
47815
|
-
* its resolver under a NextResolverContext holding the runner after it. A
|
|
47816
|
-
* resolver that re-renders on its own and renders <Next> therefore resumes at
|
|
47817
|
-
* its own position without any bookkeeping — the Next it was given is the one
|
|
47818
|
-
* made for it. A chain rendered by the hundred (a list's rows) pays two
|
|
47819
|
-
* components per position, the runner and the resolver, so nothing here is a
|
|
47820
|
-
* component that merely forwards.
|
|
47821
|
-
*/
|
|
47822
47848
|
const createComponentResolver = (resolvers, {
|
|
47823
47849
|
pure
|
|
47824
47850
|
} = {}) => {
|
|
@@ -47827,13 +47853,10 @@ const createComponentResolver = (resolvers, {
|
|
|
47827
47853
|
for (let index = 0; index < resolvers.length; index++) {
|
|
47828
47854
|
const Resolver = resolvers[index];
|
|
47829
47855
|
const isLast = index === lastIndex;
|
|
47830
|
-
|
|
47831
|
-
|
|
47832
|
-
|
|
47833
|
-
|
|
47834
|
-
})
|
|
47835
|
-
});
|
|
47836
|
-
Runner.displayName = `${Resolver.displayName || Resolver.name}Runner`;
|
|
47856
|
+
function Runner(props) {
|
|
47857
|
+
return runResolverBody(this, Resolver, props, isLast ? null : runners[index + 1]);
|
|
47858
|
+
}
|
|
47859
|
+
Runner.displayName = Resolver.displayName || Resolver.name;
|
|
47837
47860
|
runners.push(Runner);
|
|
47838
47861
|
}
|
|
47839
47862
|
const FirstRunner = runners[0];
|
|
@@ -47864,6 +47887,54 @@ const createComponentResolver = (resolvers, {
|
|
|
47864
47887
|
}
|
|
47865
47888
|
return PureRenderComponent;
|
|
47866
47889
|
};
|
|
47890
|
+
const useNextResolver = () => {
|
|
47891
|
+
if (currentNext === OUTSIDE_RESOLVER_BODY) {
|
|
47892
|
+
throw new Error("useNextResolver() called outside a resolver body: a resolver rendered by another resolver is rendered with renderResolver(Resolver, props), not as a JSX child.");
|
|
47893
|
+
}
|
|
47894
|
+
return currentNext;
|
|
47895
|
+
};
|
|
47896
|
+
const renderResolver = (Resolver, props) => {
|
|
47897
|
+
if (currentNext === OUTSIDE_RESOLVER_BODY) {
|
|
47898
|
+
throw new Error(`renderResolver(${Resolver.displayName || Resolver.name}) called outside a resolver body: only a resolver can render another one.`);
|
|
47899
|
+
}
|
|
47900
|
+
let SubRunner = subRunnerByResolver.get(Resolver);
|
|
47901
|
+
if (!SubRunner) {
|
|
47902
|
+
SubRunner = function (props) {
|
|
47903
|
+
const {
|
|
47904
|
+
[NEXT_PROP]: next,
|
|
47905
|
+
...ownProps
|
|
47906
|
+
} = props;
|
|
47907
|
+
return runResolverBody(this, Resolver, ownProps, next);
|
|
47908
|
+
};
|
|
47909
|
+
SubRunner.displayName = Resolver.displayName || Resolver.name;
|
|
47910
|
+
subRunnerByResolver.set(Resolver, SubRunner);
|
|
47911
|
+
}
|
|
47912
|
+
return createElement(SubRunner, {
|
|
47913
|
+
...props,
|
|
47914
|
+
[NEXT_PROP]: currentNext
|
|
47915
|
+
});
|
|
47916
|
+
};
|
|
47917
|
+
|
|
47918
|
+
// What useNextResolver() answers: the runner after the one whose body is
|
|
47919
|
+
// running, null for the last — and, outside any body, a value that is neither.
|
|
47920
|
+
const OUTSIDE_RESOLVER_BODY = Symbol("outside_resolver_body");
|
|
47921
|
+
let currentNext = OUTSIDE_RESOLVER_BODY;
|
|
47922
|
+
const runResolverBody = (instance, Resolver, props, next) => {
|
|
47923
|
+
const nextBefore = currentNext;
|
|
47924
|
+
currentNext = next;
|
|
47925
|
+
try {
|
|
47926
|
+
return Resolver.call(instance, props);
|
|
47927
|
+
} finally {
|
|
47928
|
+
currentNext = nextBefore;
|
|
47929
|
+
}
|
|
47930
|
+
};
|
|
47931
|
+
|
|
47932
|
+
// One runner per resolver rendered through renderResolver, made on first use:
|
|
47933
|
+
// the same component type on every render, so a resolver picked again is
|
|
47934
|
+
// updated in place and another one picked is a remount, like any child.
|
|
47935
|
+
const subRunnerByResolver = new WeakMap();
|
|
47936
|
+
// Rides on the props of a sub-runner, stripped before the body sees them.
|
|
47937
|
+
const NEXT_PROP = "navi-resolver-next";
|
|
47867
47938
|
function pureShouldComponentUpdate(nextProps) {
|
|
47868
47939
|
return shallowDiffers(this.props, nextProps);
|
|
47869
47940
|
}
|
|
@@ -48689,9 +48760,7 @@ const ButtonConfirm = ({
|
|
|
48689
48760
|
const ButtonRouteResolver = props => {
|
|
48690
48761
|
const Next = useNextResolver();
|
|
48691
48762
|
if (props.route) {
|
|
48692
|
-
return
|
|
48693
|
-
...props
|
|
48694
|
-
});
|
|
48763
|
+
return renderResolver(ButtonWithRoute, props);
|
|
48695
48764
|
}
|
|
48696
48765
|
return jsx(Next, {
|
|
48697
48766
|
...props
|
|
@@ -51289,9 +51358,7 @@ const installInputCss = () => {
|
|
|
51289
51358
|
const InputModeResolver = props => {
|
|
51290
51359
|
const Next = useNextResolver();
|
|
51291
51360
|
if (props.inputMode === "numeric" || props.inputMode === "decimal") {
|
|
51292
|
-
return
|
|
51293
|
-
...props
|
|
51294
|
-
});
|
|
51361
|
+
return renderResolver(InputModeNumericOrDecimal, props);
|
|
51295
51362
|
}
|
|
51296
51363
|
return jsx(Next, {
|
|
51297
51364
|
...props
|
|
@@ -51519,39 +51586,25 @@ const InputTypeResolver = props => {
|
|
|
51519
51586
|
// very same "icon while empty, clear button once filled" affordance without
|
|
51520
51587
|
// pretending to be a search box.
|
|
51521
51588
|
if (props.clearable && props.type !== "search") {
|
|
51522
|
-
return
|
|
51523
|
-
...props
|
|
51524
|
-
});
|
|
51589
|
+
return renderResolver(InputClearable, props);
|
|
51525
51590
|
}
|
|
51526
51591
|
if (props.type === "search") {
|
|
51527
|
-
return
|
|
51528
|
-
...props
|
|
51529
|
-
});
|
|
51592
|
+
return renderResolver(InputSearch, props);
|
|
51530
51593
|
}
|
|
51531
51594
|
if (props.type === "email") {
|
|
51532
|
-
return
|
|
51533
|
-
...props
|
|
51534
|
-
});
|
|
51595
|
+
return renderResolver(InputEmail, props);
|
|
51535
51596
|
}
|
|
51536
51597
|
if (props.type === "tel") {
|
|
51537
|
-
return
|
|
51538
|
-
...props
|
|
51539
|
-
});
|
|
51598
|
+
return renderResolver(InputTel, props);
|
|
51540
51599
|
}
|
|
51541
51600
|
if (props.type === "number") {
|
|
51542
|
-
return
|
|
51543
|
-
...props
|
|
51544
|
-
});
|
|
51601
|
+
return renderResolver(InputNumber, props);
|
|
51545
51602
|
}
|
|
51546
51603
|
if (props.type === "color") {
|
|
51547
|
-
return
|
|
51548
|
-
...props
|
|
51549
|
-
});
|
|
51604
|
+
return renderResolver(InputColor, props);
|
|
51550
51605
|
}
|
|
51551
51606
|
if (props.type === "datetime-local") {
|
|
51552
|
-
return
|
|
51553
|
-
...props
|
|
51554
|
-
});
|
|
51607
|
+
return renderResolver(InputDatetimeLocal, props);
|
|
51555
51608
|
}
|
|
51556
51609
|
return jsx(Next, {
|
|
51557
51610
|
...props
|
|
@@ -51664,9 +51717,7 @@ const InputDatetimeLocal = props => {
|
|
|
51664
51717
|
const InputWithListResolver = props => {
|
|
51665
51718
|
const Next = useNextResolver();
|
|
51666
51719
|
if (props["navi-list"]) {
|
|
51667
|
-
return
|
|
51668
|
-
...props
|
|
51669
|
-
});
|
|
51720
|
+
return renderResolver(InputWithList, props);
|
|
51670
51721
|
}
|
|
51671
51722
|
return jsx(Next, {
|
|
51672
51723
|
...props
|
|
@@ -51773,9 +51824,7 @@ const ChevronDownSvg$1 = () => {
|
|
|
51773
51824
|
const InputWithSuggestionsResolver = props => {
|
|
51774
51825
|
const Next = useNextResolver();
|
|
51775
51826
|
if (props["navi-suggestions"]) {
|
|
51776
|
-
return
|
|
51777
|
-
...props
|
|
51778
|
-
});
|
|
51827
|
+
return renderResolver(InputTextualWithSuggestions, props);
|
|
51779
51828
|
}
|
|
51780
51829
|
return jsx(Next, {
|
|
51781
51830
|
...props
|
|
@@ -59279,34 +59328,44 @@ const css$E = /* css */`
|
|
|
59279
59328
|
* `showModal()`'d (native focus trap, `Escape`-to-cancel, hardware
|
|
59280
59329
|
* back-button dismissal, rest-of-document made inert), without one it is
|
|
59281
59330
|
* shown through the Popover API and the page behind stays live.
|
|
59282
|
-
* @param {boolean} [props.dockedOnSmallTouchScreen] - Turns
|
|
59283
|
-
*
|
|
59284
|
-
* screen, and leaves it alone otherwise
|
|
59285
|
-
*
|
|
59286
|
-
* the
|
|
59287
|
-
*
|
|
59288
|
-
*
|
|
59289
|
-
*
|
|
59290
|
-
*
|
|
59291
|
-
*
|
|
59292
|
-
*
|
|
59293
|
-
*
|
|
59331
|
+
* @param {boolean|"top"|"bottom"} [props.dockedOnSmallTouchScreen] - Turns
|
|
59332
|
+
* the dialog into a sheet (docked flush to one edge, full width) on a small
|
|
59333
|
+
* touch screen, and leaves it alone otherwise: under a mouse the centered box
|
|
59334
|
+
* is already the right shape, while on a phone a centered box ends up cramped
|
|
59335
|
+
* between the keyboard and the top of the screen. The value says which edge
|
|
59336
|
+
* the sheet rests on. `true` (or `"top"`) rests it on the top edge, out of
|
|
59337
|
+
* the virtual keyboard's way: a field tapped in the sheet raises the keyboard
|
|
59338
|
+
* below it, and the question and the field stay where the finger found them.
|
|
59339
|
+
* `"bottom"` rests it on the bottom edge, where the thumbs are — for a sheet
|
|
59340
|
+
* that is read and tapped (a list, a couple of buttons, a confirmation) and
|
|
59341
|
+
* holds nothing that raises a keyboard; one that does is reflowed into the
|
|
59342
|
+
* strip left above the keyboard at every keystroke. The edge is said here
|
|
59343
|
+
* rather than through `positionArea`, which places both shapes:
|
|
59344
|
+
* `positionArea="bottom"` would also pin the centered box to the bottom of a
|
|
59345
|
+
* desktop window. Both halves of the name matter (`smallTouchScreenSignal`):
|
|
59346
|
+
* touch alone would dock a big touch screen — a tablet, a kiosk panel — a
|
|
59347
|
+
* whole screen away from where the finger just tapped, and size alone would
|
|
59348
|
+
* dock a narrow desktop window, which is still a mouse. It supplies defaults
|
|
59349
|
+
* for `positionArea`, `marginWithContainer`, `expandX` and `scrollCapture`,
|
|
59350
|
+
* so any of them can still be pinned explicitly — including `expandX={false}`,
|
|
59294
59351
|
* which opts the docked dialog out of the full-width stretch and leaves it a
|
|
59295
|
-
* floating box
|
|
59352
|
+
* floating box against its edge. It also withdraws `maxWidth` while docked: a
|
|
59296
59353
|
* sheet is container-wide by definition, and a `maxWidth` is an answer about
|
|
59297
59354
|
* the *centered* shape, so the two can be stated together (`maxWidth="16rem"
|
|
59298
59355
|
* dockedOnSmallTouchScreen`) and each applies where it means something.
|
|
59299
59356
|
* `minWidth` needs no such rule — its floor is below the full width — and
|
|
59300
59357
|
* `maxHeight`/`minHeight` keep applying, a sheet being content-tall.
|
|
59301
|
-
* Ignored entirely when `expandY`
|
|
59302
|
-
*
|
|
59303
|
-
*
|
|
59304
|
-
*
|
|
59305
|
-
*
|
|
59306
|
-
*
|
|
59307
|
-
*
|
|
59308
|
-
*
|
|
59309
|
-
*
|
|
59358
|
+
* Ignored entirely when `expandY` (or `expand`) is set: a dialog already
|
|
59359
|
+
* filling the height touches both edges, so docking could only take away the
|
|
59360
|
+
* shape the caller asked for. Re-resolves live as the pointer type or the
|
|
59361
|
+
* window size changes. A sheet is also pushed back through the edge it rests
|
|
59362
|
+
* on to close it (down for a bottom sheet, up for a top one), held by its
|
|
59363
|
+
* header (a `Box` with the `header` prop) and by anything else carrying
|
|
59364
|
+
* `data-swipe-grip`. The rest of the sheet is left to what it holds, so a
|
|
59365
|
+
* board something is dragged across keeps its own gestures. See
|
|
59366
|
+
* `swipe_to_close.js`. In dev, a `"bottom"` sheet found holding a field that
|
|
59367
|
+
* raises the keyboard is warned about at open, on any screen — the mistake
|
|
59368
|
+
* itself only shows on a phone.
|
|
59310
59369
|
* @param {string} [props.positionArea="center"] - Where to dock the dialog
|
|
59311
59370
|
* within its container (the viewport for `layer="top"`, the positioned
|
|
59312
59371
|
* ancestor for `layer="local"`) — Dialog is never anchored to a real
|
|
@@ -59672,28 +59731,28 @@ const DialogLocal = props => {
|
|
|
59672
59731
|
* own to render: a modal's is the native `::backdrop`, and `backdrop={false}`
|
|
59673
59732
|
* has none at all.
|
|
59674
59733
|
*/
|
|
59675
|
-
// What a dialog turns into on a small touch screen
|
|
59676
|
-
//
|
|
59677
|
-
//
|
|
59678
|
-
//
|
|
59734
|
+
// What a dialog turns into on a small touch screen: a sheet flush against one
|
|
59735
|
+
// edge of the screen. Which edge is the caller's word (the prop's value, see
|
|
59736
|
+
// its JSDoc), the top one unless told "bottom": the cheap mistake must be the
|
|
59737
|
+
// default one — a sheet docked top by mistake is a little farther from the
|
|
59738
|
+
// thumb, a sheet docked bottom by mistake fights the virtual keyboard, which
|
|
59739
|
+
// rises from that very edge, on every keystroke.
|
|
59679
59740
|
// Only defaults: an explicitly passed prop still wins, so the docked shape can
|
|
59680
59741
|
// be adjusted one axis at a time instead of being all-or-nothing.
|
|
59681
59742
|
const DOCKED = {
|
|
59682
|
-
positionArea: "bottom",
|
|
59683
59743
|
marginWithContainer: 0,
|
|
59684
59744
|
expandX: true,
|
|
59685
|
-
// A sheet
|
|
59686
|
-
//
|
|
59687
|
-
// reasoning as "bottom" above, applied to the gesture instead of the shape.
|
|
59745
|
+
// A sheet is dragged with a thumb, and a drag that runs past its own edge
|
|
59746
|
+
// must not land on the page behind it.
|
|
59688
59747
|
scrollCapture: true
|
|
59689
59748
|
};
|
|
59690
59749
|
|
|
59691
|
-
// Where a
|
|
59692
|
-
// with `header`, plus anything the application marked as one more.
|
|
59693
|
-
// else in the sheet is content the finger came to operate — a board
|
|
59694
|
-
// dragged across, a list, a map — and a press there belongs to it. A
|
|
59695
|
-
// no header and nothing marked is not pushed
|
|
59696
|
-
// own controls, by the backdrop and by Escape.
|
|
59750
|
+
// Where a sheet is held to push it back through its edge: the strip a Box
|
|
59751
|
+
// declares with `header`, plus anything the application marked as one more.
|
|
59752
|
+
// Everything else in the sheet is content the finger came to operate — a board
|
|
59753
|
+
// a piece is dragged across, a list, a map — and a press there belongs to it. A
|
|
59754
|
+
// sheet with no header and nothing marked is not pushed back at all; it is
|
|
59755
|
+
// closed by its own controls, by the backdrop and by Escape.
|
|
59697
59756
|
const DOCKED_SWIPE_GRIP = "[data-header],[data-swipe-grip]";
|
|
59698
59757
|
const useDialogProps = props => {
|
|
59699
59758
|
const backdropProps = {};
|
|
@@ -59799,12 +59858,12 @@ const useDialogProps = props => {
|
|
|
59799
59858
|
// Only a small touch screen changes anything: on a mouse — and on a touch
|
|
59800
59859
|
// screen too big to reach the bottom edge of — a dialog already wants to be
|
|
59801
59860
|
// the centered box it is by default, so there is nothing to resolve.
|
|
59802
|
-
// expandY cancels the docking outright:
|
|
59803
|
-
//
|
|
59804
|
-
//
|
|
59805
|
-
// caller asked for (and arm a swipe-down on something that never rose).
|
|
59861
|
+
// expandY cancels the docking outright: a dialog already filling the height
|
|
59862
|
+
// touches both edges — all docking could still do is take away the shape
|
|
59863
|
+
// the caller asked for (and arm a swipe on something that never rose).
|
|
59806
59864
|
const isDocked = dockedOnSmallTouchScreen && smallTouchScreenSignal.value && !expandY;
|
|
59807
|
-
const
|
|
59865
|
+
const dockedEdge = dockedOnSmallTouchScreen === "bottom" ? "bottom" : "top";
|
|
59866
|
+
const positionArea = positionAreaProp ?? (isDocked ? dockedEdge : "center");
|
|
59808
59867
|
const marginWithContainer = marginWithContainerProp ?? (isDocked ? DOCKED.marginWithContainer :
|
|
59809
59868
|
// A share of whatever holds the dialog: the app's own screen for a
|
|
59810
59869
|
// top-layer one — where appw is exactly "3% of the container", the
|
|
@@ -59866,12 +59925,12 @@ const useDialogProps = props => {
|
|
|
59866
59925
|
y: "center",
|
|
59867
59926
|
x: "center"
|
|
59868
59927
|
};
|
|
59869
|
-
// Pushing the sheet back
|
|
59870
|
-
//
|
|
59871
|
-
// actually resting on
|
|
59872
|
-
//
|
|
59873
|
-
const
|
|
59874
|
-
const onSwipePointerDown =
|
|
59928
|
+
// Pushing the sheet back through the edge it rests on closes it — the way
|
|
59929
|
+
// it came in, and the way the thumb on that edge already pushes. Only a sheet
|
|
59930
|
+
// actually resting on an edge: anywhere else the gesture would send the
|
|
59931
|
+
// dialog somewhere it never came from.
|
|
59932
|
+
const swipeToCloseSide = isDocked && (parsedPositionArea.y === "top" || parsedPositionArea.y === "bottom") ? parsedPositionArea.y : null;
|
|
59933
|
+
const onSwipePointerDown = swipeToCloseSide ? createSwipeToClose(swipeToCloseSide, {
|
|
59875
59934
|
grip: DOCKED_SWIPE_GRIP
|
|
59876
59935
|
}) : null;
|
|
59877
59936
|
// A corner sitting exactly on the container's own corner must not be
|
|
@@ -60503,12 +60562,12 @@ const useDialogProps = props => {
|
|
|
60503
60562
|
"data-flush-right": flushEdges.right ? "" : undefined,
|
|
60504
60563
|
"data-flush-bottom": flushEdges.bottom ? "" : undefined,
|
|
60505
60564
|
"data-flush-left": flushEdges.left ? "" : undefined,
|
|
60506
|
-
"data-swipe-to-close":
|
|
60565
|
+
"data-swipe-to-close": swipeToCloseSide ?? undefined,
|
|
60507
60566
|
// The axis the sheet travels on when it is pushed back, said to the shared
|
|
60508
60567
|
// gesture layer: it is what a box travelling inside the sheet reads to know
|
|
60509
60568
|
// this axis is already walked (see @jsenv/dom's drag_to_travel).
|
|
60510
|
-
"data-drag-travel":
|
|
60511
|
-
"data-travel-by-drag":
|
|
60569
|
+
"data-drag-travel": swipeToCloseSide ? SWIPE_AXIS_BY_SIDE[swipeToCloseSide] : undefined,
|
|
60570
|
+
"data-travel-by-drag": swipeToCloseSide ? SWIPE_AXIS_BY_SIDE[swipeToCloseSide] : undefined,
|
|
60512
60571
|
"onPointerDown": e => {
|
|
60513
60572
|
rest.onPointerDown?.(e);
|
|
60514
60573
|
onSwipePointerDown?.(e);
|
|
@@ -62302,8 +62361,8 @@ const css$C = /* css */`@layer navi {
|
|
|
62302
62361
|
* @param {string} [props.positionAreaFixed] - **Popover-only**, same guard.
|
|
62303
62362
|
* @param {string} [props.positionAreaWhenAnchorIsInvalid] - **Popover-only**,
|
|
62304
62363
|
* same guard.
|
|
62305
|
-
* @param {boolean} [props.dockedOnSmallTouchScreen] -
|
|
62306
|
-
* popover is never a
|
|
62364
|
+
* @param {boolean|"top"|"bottom"} [props.dockedOnSmallTouchScreen] -
|
|
62365
|
+
* **Dialog-only** (a popover is never a sheet), destructured out for the same reason
|
|
62307
62366
|
* turned around: it must not land on the popover element as a stray DOM
|
|
62308
62367
|
* attribute when the screen-size resolution picks `mode="popover"`. Where
|
|
62309
62368
|
* that resolution lands is what decides whether it applies at all, so a
|
|
@@ -62331,7 +62390,7 @@ const css$C = /* css */`@layer navi {
|
|
|
62331
62390
|
* honoured in either mode — a wall-less `Dialog` is shown through the
|
|
62332
62391
|
* Popover API rather than `showModal()` — so which mode the screen-size
|
|
62333
62392
|
* resolution picks says nothing about whether the page behind stays live.
|
|
62334
|
-
* It is also what makes a sheet docked to
|
|
62393
|
+
* It is also what makes a sheet docked to an edge of a phone's screen
|
|
62335
62394
|
* (`dockedOnSmallTouchScreen`) non-modal.
|
|
62336
62395
|
* @param {"auto"|"discrete"|"invisible"} [props.backdropVariant] - Forwarded
|
|
62337
62396
|
* as-is to whichever component renders (both understand it identically):
|
|
@@ -62527,9 +62586,7 @@ const css$B = /* css */`.navi_picker_callout_dock > [data-picker-content] {
|
|
|
62527
62586
|
const PickerCustomResolver = props => {
|
|
62528
62587
|
import.meta.css = [css$B, "@jsenv/navi/src/control/picker/picker_custom.jsx"];
|
|
62529
62588
|
if (props.children === undefined) {
|
|
62530
|
-
return
|
|
62531
|
-
...props
|
|
62532
|
-
});
|
|
62589
|
+
return renderResolver(PickerNative, props);
|
|
62533
62590
|
}
|
|
62534
62591
|
if (props.mode === "callout") {
|
|
62535
62592
|
// A tooltip is an icon one presses, unless told otherwise. Own-property
|
|
@@ -62591,14 +62648,12 @@ const PickerCustomResolver = props => {
|
|
|
62591
62648
|
// how a field says its value is a JS one, kept beside the DOM (see
|
|
62592
62649
|
// controller_registry.js) — the same thing type="array"/"object" already
|
|
62593
62650
|
// say for their shapes.
|
|
62594
|
-
return
|
|
62651
|
+
return renderResolver(PickerCustom, {
|
|
62595
62652
|
...props,
|
|
62596
62653
|
type: "navi_js"
|
|
62597
62654
|
});
|
|
62598
62655
|
}
|
|
62599
|
-
return
|
|
62600
|
-
...props
|
|
62601
|
-
});
|
|
62656
|
+
return renderResolver(PickerCustom, props);
|
|
62602
62657
|
};
|
|
62603
62658
|
const PickerNative = props => {
|
|
62604
62659
|
const Next = useNextResolver();
|
|
@@ -63210,9 +63265,9 @@ const PickerCustom = props => {
|
|
|
63210
63265
|
});
|
|
63211
63266
|
}
|
|
63212
63267
|
}
|
|
63213
|
-
return
|
|
63268
|
+
return renderResolver(PickerContentInsidePopup, {
|
|
63214
63269
|
...pickerProps,
|
|
63215
|
-
mode
|
|
63270
|
+
mode
|
|
63216
63271
|
});
|
|
63217
63272
|
};
|
|
63218
63273
|
|
|
@@ -64479,14 +64534,10 @@ const createItemTracker = (onChange) => {
|
|
|
64479
64534
|
const ListItemHeaderOrFooterResolver = props => {
|
|
64480
64535
|
const Next = useNextResolver();
|
|
64481
64536
|
if (props.header) {
|
|
64482
|
-
return
|
|
64483
|
-
...props
|
|
64484
|
-
});
|
|
64537
|
+
return renderResolver(ListItemHeader, props);
|
|
64485
64538
|
}
|
|
64486
64539
|
if (props.footer) {
|
|
64487
|
-
return
|
|
64488
|
-
...props
|
|
64489
|
-
});
|
|
64540
|
+
return renderResolver(ListItemFooter, props);
|
|
64490
64541
|
}
|
|
64491
64542
|
return jsx(Next, {
|
|
64492
64543
|
...props
|
|
@@ -64718,9 +64769,7 @@ const ListSelectableContext = createContext(false);
|
|
|
64718
64769
|
const ListSelectableResolver = props => {
|
|
64719
64770
|
const Next = useNextResolver();
|
|
64720
64771
|
if (props.selectable) {
|
|
64721
|
-
return
|
|
64722
|
-
...props
|
|
64723
|
-
});
|
|
64772
|
+
return renderResolver(ListSelectable, props);
|
|
64724
64773
|
}
|
|
64725
64774
|
return jsx(ListSelectableContext.Provider, {
|
|
64726
64775
|
value: false,
|
|
@@ -65020,7 +65069,7 @@ const ListItemSelectableResolver = props => {
|
|
|
65020
65069
|
const isHeaderOrFooter = Boolean(props.header || props.footer);
|
|
65021
65070
|
const selectable = props.selectable ?? (isHeaderOrFooter || props.role === "presentation" ? false : listSelectable);
|
|
65022
65071
|
if (selectable) {
|
|
65023
|
-
return
|
|
65072
|
+
return renderResolver(ListItemSelectable, {
|
|
65024
65073
|
...props,
|
|
65025
65074
|
selectable: true
|
|
65026
65075
|
});
|
|
@@ -70263,14 +70312,10 @@ const generateTimeSlots = (min, max, stepSeconds) => {
|
|
|
70263
70312
|
const PickerPresetResolver = props => {
|
|
70264
70313
|
const Next = useNextResolver();
|
|
70265
70314
|
if (props.type === "navi_time") {
|
|
70266
|
-
return
|
|
70267
|
-
...props
|
|
70268
|
-
});
|
|
70315
|
+
return renderResolver(PickerNaviTime, props);
|
|
70269
70316
|
}
|
|
70270
70317
|
if (props.type === "navi_minute") {
|
|
70271
|
-
return
|
|
70272
|
-
...props
|
|
70273
|
-
});
|
|
70318
|
+
return renderResolver(PickerNaviMinute, props);
|
|
70274
70319
|
}
|
|
70275
70320
|
return jsx(Next, {
|
|
70276
70321
|
...props
|
|
@@ -71068,59 +71113,37 @@ const PencilSvg = () => {
|
|
|
71068
71113
|
const PickerTypeResolver = props => {
|
|
71069
71114
|
const Next = useNextResolver();
|
|
71070
71115
|
if (props.type === "color") {
|
|
71071
|
-
return
|
|
71072
|
-
...props
|
|
71073
|
-
});
|
|
71116
|
+
return renderResolver(PickerColor, props);
|
|
71074
71117
|
}
|
|
71075
71118
|
if (props.type === "datetime") {
|
|
71076
|
-
return
|
|
71077
|
-
...props
|
|
71078
|
-
});
|
|
71119
|
+
return renderResolver(PickerDatetime, props);
|
|
71079
71120
|
}
|
|
71080
71121
|
if (props.type === "date") {
|
|
71081
|
-
return
|
|
71082
|
-
...props
|
|
71083
|
-
});
|
|
71122
|
+
return renderResolver(PickerDate, props);
|
|
71084
71123
|
}
|
|
71085
71124
|
if (props.type === "month") {
|
|
71086
|
-
return
|
|
71087
|
-
...props
|
|
71088
|
-
});
|
|
71125
|
+
return renderResolver(PickerMonth, props);
|
|
71089
71126
|
}
|
|
71090
71127
|
if (props.type === "week") {
|
|
71091
|
-
return
|
|
71092
|
-
...props
|
|
71093
|
-
});
|
|
71128
|
+
return renderResolver(PickerWeek, props);
|
|
71094
71129
|
}
|
|
71095
71130
|
if (props.type === "time") {
|
|
71096
|
-
return
|
|
71097
|
-
...props
|
|
71098
|
-
});
|
|
71131
|
+
return renderResolver(PickerTime, props);
|
|
71099
71132
|
}
|
|
71100
71133
|
if (props.type === "duration") {
|
|
71101
|
-
return
|
|
71102
|
-
...props
|
|
71103
|
-
});
|
|
71134
|
+
return renderResolver(PickerDuration, props);
|
|
71104
71135
|
}
|
|
71105
71136
|
if (props.type === "file") {
|
|
71106
|
-
return
|
|
71107
|
-
...props
|
|
71108
|
-
});
|
|
71137
|
+
return renderResolver(PickerFile, props);
|
|
71109
71138
|
}
|
|
71110
71139
|
if (props.type === "text") {
|
|
71111
|
-
return
|
|
71112
|
-
...props
|
|
71113
|
-
});
|
|
71140
|
+
return renderResolver(PickerText, props);
|
|
71114
71141
|
}
|
|
71115
71142
|
if (props.type === "array") {
|
|
71116
|
-
return
|
|
71117
|
-
...props
|
|
71118
|
-
});
|
|
71143
|
+
return renderResolver(PickerArray, props);
|
|
71119
71144
|
}
|
|
71120
71145
|
if (props.type === "object") {
|
|
71121
|
-
return
|
|
71122
|
-
...props
|
|
71123
|
-
});
|
|
71146
|
+
return renderResolver(PickerObject, props);
|
|
71124
71147
|
}
|
|
71125
71148
|
return jsx(Next, {
|
|
71126
71149
|
...props
|
|
@@ -74972,7 +74995,7 @@ const css$n = /* css */`.navi_split_button {
|
|
|
74972
74995
|
* dialogExpand?: boolean,
|
|
74973
74996
|
* dialogExpandX?: boolean,
|
|
74974
74997
|
* dialogExpandY?: boolean,
|
|
74975
|
-
* dockedOnSmallTouchScreen?: boolean,
|
|
74998
|
+
* dockedOnSmallTouchScreen?: boolean | "top" | "bottom",
|
|
74976
74999
|
* marginWithContainer?: number | string,
|
|
74977
75000
|
* backdrop?: boolean,
|
|
74978
75001
|
* backdropVariant?: "auto" | "discrete" | "invisible",
|
|
@@ -84249,7 +84272,9 @@ const css = /* css */`.navi_side_panel {
|
|
|
84249
84272
|
* closes the panel on an outside click instead, and also enables trapping
|
|
84250
84273
|
* Tab navigation inside the panel (`focusCapture`) — closing on outside
|
|
84251
84274
|
* interaction only makes sense paired with not letting focus silently
|
|
84252
|
-
* leave the panel first.
|
|
84275
|
+
* leave the panel first. A box of the page whose press must not close the
|
|
84276
|
+
* panel (a card that fills it) names the panel:
|
|
84277
|
+
* `data-navi-popup-inside={id}` — see docs/popup_backdrop.md.
|
|
84253
84278
|
* @param {boolean} [props.swipeToClose=true] - Pushing the panel back
|
|
84254
84279
|
* towards the edge it is docked to closes it: the panel follows the
|
|
84255
84280
|
* pointer and finishes leaving (or comes back to rest) when it is
|
|
@@ -84384,6 +84409,7 @@ SidePanel.Foot = SidePanelFoot;
|
|
|
84384
84409
|
|
|
84385
84410
|
const createSlot = (SlotRenderer = Box) => {
|
|
84386
84411
|
const slotPropsSignal = signal();
|
|
84412
|
+
let filler = null;
|
|
84387
84413
|
const Slot = () => {
|
|
84388
84414
|
const props = slotPropsSignal.value;
|
|
84389
84415
|
return jsx(SlotRenderer, {
|
|
@@ -84392,9 +84418,18 @@ const createSlot = (SlotRenderer = Box) => {
|
|
|
84392
84418
|
});
|
|
84393
84419
|
};
|
|
84394
84420
|
const SlotFill = props => {
|
|
84421
|
+
const fillerRef = useRef();
|
|
84422
|
+
filler = fillerRef;
|
|
84395
84423
|
slotPropsSignal.value = props;
|
|
84396
84424
|
useLayoutEffect(() => {
|
|
84397
84425
|
return () => {
|
|
84426
|
+
// Within one diff preact mounts the newcomer before unmounting the
|
|
84427
|
+
// leaver, so the leaver may no longer be the filler by the time it
|
|
84428
|
+
// is cleaned up.
|
|
84429
|
+
if (filler !== fillerRef) {
|
|
84430
|
+
return;
|
|
84431
|
+
}
|
|
84432
|
+
filler = null;
|
|
84398
84433
|
slotPropsSignal.value = null;
|
|
84399
84434
|
};
|
|
84400
84435
|
}, []);
|