@jsenv/navi 0.27.0 → 0.27.2

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.
@@ -3,7 +3,7 @@ import { isValidElement, createContext, h, toChildArray, render, Fragment, clone
3
3
  import { useErrorBoundary, useLayoutEffect, useEffect, useContext, useMemo, useRef, useState, useCallback, useId } from "preact/hooks";
4
4
  import { jsxs, jsx, Fragment as Fragment$1 } from "preact/jsx-runtime";
5
5
  import { signal, effect, computed, batch, useSignal } from "@preact/signals";
6
- import { createIterableWeakSet, createEventGroupLogger, mergeOneStyle, normalizeStyle, createPubSub, dispatchInternalCustomEvent, getElementSignature, findEvent, mergeTwoStyles, normalizeStyles, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, findBefore, findAfter, createValueEffect, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, allowWheelThrough, dispatchPublicCustomEvent, resolveCSSColor, createStyleController, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, measureLongestVisualLineWidth, findFocusDelegateTarget, getKeyboardEventDefaultAction, resolveCSSSize, activeElementSignal, hasCSSSizeUnit, resolveOklchLightness, contrastColor, dispatchCustomEvent, initFocusGroup, elementIsFocusable, findFocusable, trapScrollInside, trapFocusInside, snapToPixel, scrollIntoViewScoped, dragAfterThreshold, getScrollContainer, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement, measureWidestChildRow } from "@jsenv/dom";
6
+ import { createIterableWeakSet, createEventGroupLogger, mergeOneStyle, normalizeStyle, createPubSub, findEvent, dispatchInternalCustomEvent, getElementSignature, mergeTwoStyles, normalizeStyles, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, findBefore, findAfter, createValueEffect, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, allowWheelThrough, dispatchPublicCustomEvent, resolveCSSColor, createStyleController, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, measureLongestVisualLineWidth, findFocusDelegateTarget, getKeyboardEventDefaultAction, resolveCSSSize, activeElementSignal, hasCSSSizeUnit, resolveOklchLightness, contrastColor, dispatchCustomEvent, initFocusGroup, elementIsFocusable, findFocusable, trapScrollInside, trapFocusInside, snapToPixel, scrollIntoViewScoped, dragAfterThreshold, getScrollContainer, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement, measureWidestChildRow } from "@jsenv/dom";
7
7
  export { contrastColor, startDragToReorder } from "@jsenv/dom";
8
8
  import { prefixFirstAndIndentRemainingLines } from "@jsenv/humanize";
9
9
  import { createValidity } from "@jsenv/validity";
@@ -7403,9 +7403,12 @@ const addInputEffect = (
7403
7403
  };
7404
7404
 
7405
7405
  // Standard user input (typing)
7406
- input.addEventListener("input", onEvent);
7406
+ const onInput = (e) => {
7407
+ onEvent(e);
7408
+ };
7409
+ input.addEventListener("input", onInput);
7407
7410
  addTeardown(() => {
7408
- input.removeEventListener("input", onEvent);
7411
+ input.removeEventListener("input", onInput);
7409
7412
  });
7410
7413
 
7411
7414
  // Form reset - need to check the form
@@ -7424,27 +7427,28 @@ const addInputEffect = (
7424
7427
  input.removeEventListener("paste", onEvent);
7425
7428
  });
7426
7429
 
7427
- if (input.type === "radio") {
7430
+ input.addEventListener("navi_ui_state_change", (e) => {
7428
7431
  // radios are unchecked by an internal setUIState call when another radio is checked.
7429
7432
  // navi_ui_state_change is dispatched whenever setUIState changes state, so we
7430
7433
  // listen here to keep currentState in sync — otherwise input_effect thinks the
7431
7434
  // radio is still checked and ignores the next user click as "state unchanged".
7432
- input.addEventListener("navi_ui_state_change", () => {
7433
- currentState = getState();
7434
- });
7435
- }
7436
-
7437
- const onNaviClear = (e) => {
7438
- // "navi_clear" behaves like an async event
7439
- // a bit like form reset because
7440
- // our action will be updated async after the component re-renders
7441
- // and we need to wait that to happen to properly call action with the right value
7442
- debugInteraction(e, `navi_clear received, scheduling callback`);
7443
- onAsyncEvent(e, { skipDebounce: true });
7444
- };
7445
- input.addEventListener("navi_clear", onNaviClear);
7446
- addTeardown(() => {
7447
- input.removeEventListener("navi_clear", onNaviClear);
7435
+ if (input.type === "radio") {
7436
+ currentState = e.detail.value;
7437
+ }
7438
+ const clearEvent = findEvent(
7439
+ e,
7440
+ (eInChain) =>
7441
+ eInChain.type === "navi_set_ui_state" && eInChain.detail.isClear,
7442
+ );
7443
+ const isClear = Boolean(clearEvent);
7444
+ if (isClear) {
7445
+ // "navi_clear" behaves like an async event
7446
+ // a bit like form reset because
7447
+ // our action will be updated async after the component re-renders
7448
+ // and we need to wait that to happen to properly call action with the right value
7449
+ debugInteraction(e, `navi_clear received, scheduling callback`);
7450
+ onAsyncEvent(e, { skipDebounce: true });
7451
+ }
7448
7452
  });
7449
7453
 
7450
7454
  return teardown;
@@ -24995,6 +24999,9 @@ const routeArgs = (args, { event, action, other }) => {
24995
24999
  return other(...args);
24996
25000
  };
24997
25001
 
25002
+ const triggerStringAction = (actionName, event) => {
25003
+ return resolveActionProp(actionName)(event);
25004
+ };
24998
25005
  const resolveActionProp = (action) => {
24999
25006
  if (typeof action === "string") {
25000
25007
  const naviAction = STRING_ACTIONS[action];
@@ -25103,12 +25110,12 @@ const update = createUICallback({
25103
25110
  return requestUpdate(event, value);
25104
25111
  },
25105
25112
  });
25106
- const requestUpdate = (event, value) => {
25113
+ const requestUpdate = (event, value, { isClear } = {}) => {
25107
25114
  const actionTarget = getActionTarget(event);
25108
25115
  if (!actionTarget) {
25109
25116
  return false;
25110
25117
  }
25111
- return dispatchRequestSetUIState(actionTarget, value, { event });
25118
+ return dispatchRequestSetUIState(actionTarget, value, { event, isClear });
25112
25119
  };
25113
25120
 
25114
25121
  /**
@@ -25192,12 +25199,20 @@ const requestClosestAction = (event) => {
25192
25199
  const clear = createUICallback({
25193
25200
  name: "clear",
25194
25201
  event: (event) => {
25195
- update("", { event });
25196
- return requestClose(event);
25202
+ requestUpdate(event, "", { isClear: true });
25203
+ const expandableEl = event.currentTarget.closest("[aria-expanded]");
25204
+ if (expandableEl) {
25205
+ return requestClose(event);
25206
+ }
25207
+ return true;
25197
25208
  },
25198
25209
  action: (v, { event }) => {
25199
- update("", { event });
25200
- return requestClose(event);
25210
+ requestUpdate(event, "", { isClear: true });
25211
+ const expandableEl = event.currentTarget.closest("[aria-expanded]");
25212
+ if (expandableEl) {
25213
+ return requestClose(event);
25214
+ }
25215
+ return true;
25201
25216
  },
25202
25217
  });
25203
25218
  /**
@@ -25227,13 +25242,13 @@ const close = createUICallback({
25227
25242
  const cancel = createUICallback({
25228
25243
  name: "cancel",
25229
25244
  event: (event) => {
25230
- return requestClose(event, { cancel: true });
25245
+ return requestClose(event, { isCancel: true });
25231
25246
  },
25232
25247
  action: (_, { event }) => {
25233
- return requestClose(event, { cancel: true });
25248
+ return requestClose(event, { isCancel: true });
25234
25249
  },
25235
25250
  });
25236
- const requestClose = (event, { cancel = false } = {}) => {
25251
+ const requestClose = (event, { isCancel = false } = {}) => {
25237
25252
  const currentTarget = event.currentTarget;
25238
25253
  const expandableEl = currentTarget.closest("[aria-expanded]");
25239
25254
  if (!expandableEl) {
@@ -25245,7 +25260,7 @@ const requestClose = (event, { cancel = false } = {}) => {
25245
25260
  }
25246
25261
  return dispatchCustomEvent(expandableEl, "navi_request_close", {
25247
25262
  event,
25248
- cancel,
25263
+ isCancel,
25249
25264
  });
25250
25265
  };
25251
25266
 
@@ -25612,7 +25627,7 @@ const useControlProps = (props, {
25612
25627
  name: "navi_change",
25613
25628
  callback: asAction
25614
25629
  };
25615
- enterEffect = e => resolveActionProp("send")(e);
25630
+ enterEffect = e => triggerStringAction("send", e);
25616
25631
  if (picker) {
25617
25632
  mousedownInteraction = {
25618
25633
  name: "mousedown to open picker",
@@ -30409,6 +30424,10 @@ const InputSearch = props => {
30409
30424
  const InputSearchUI = ({
30410
30425
  icon
30411
30426
  }) => {
30427
+ const ctx = useContext(InputNativeContext);
30428
+ const {
30429
+ id
30430
+ } = ctx;
30412
30431
  return jsxs(Fragment$1, {
30413
30432
  children: [icon === undefined && jsx(InputLeftSlot, {
30414
30433
  children: jsx(Icon, {
@@ -30417,16 +30436,12 @@ const InputSearchUI = ({
30417
30436
  })
30418
30437
  }), jsx(InputRightSlot, {
30419
30438
  hideWhileEmpty: true,
30439
+ "action-target": id,
30420
30440
  onClick: e => {
30421
30441
  const input = e.currentTarget;
30422
30442
  const allowed = dispatchRequestInteraction(input, e);
30423
30443
  if (allowed) {
30424
- dispatchRequestSetUIState(input, "", {
30425
- event: e
30426
- });
30427
- dispatchCustomEvent(input, "navi_clear", {
30428
- event: e
30429
- });
30444
+ triggerStringAction("clear", e);
30430
30445
  }
30431
30446
  },
30432
30447
  children: jsx(Icon, {
@@ -31905,7 +31920,7 @@ const PickerCustom = props => {
31905
31920
  valueAtOpenRef.current = getPickerInputUIState(ref.current);
31906
31921
  };
31907
31922
  const onClose = e => {
31908
- const cancelEvent = findEvent(e, eInChain => eInChain.type === "navi_request_close" && eInChain.detail.cancel);
31923
+ const cancelEvent = findEvent(e, eInChain => eInChain.type === "navi_request_close" && eInChain.detail.isCancel);
31909
31924
  const isCancel = Boolean(cancelEvent);
31910
31925
  expandedRef.current = false;
31911
31926
  setExpanded(false);
@@ -34663,7 +34678,7 @@ const css$l = /* css */`
34663
34678
  --x-list-outline-offset: calc(-1 * var(--list-border-width));
34664
34679
 
34665
34680
  outline-width: var(--x-list-outline-width);
34666
- outline-color: var(--x-list-outline-color);
34681
+ outline-color: var(--list-outline-color);
34667
34682
  outline-offset: var(--x-list-outline-offset);
34668
34683
 
34669
34684
  &[data-focus] {
@@ -35521,6 +35536,8 @@ const PickerDefaultUI = () => {
35521
35536
  children: value
35522
35537
  });
35523
35538
  };
35539
+ Picker.Placeholder = PickerPlaceholder;
35540
+ Picker.Value = PickerValue;
35524
35541
  Picker.UI = PickerDefaultUI;
35525
35542
  Picker.UI.Date = PickerDateUI;
35526
35543
  Picker.UI.Time = PickerTimeUI;