import { createChangeEventDetails, createGenericEventDetails, REASONS } from "../../internals/change-event-details.jsx";
import { CHANGE_VALUE_TICK_DELAY, DEFAULT_STEP, SCROLLING_POINTER_MOVE_DISTANCE, START_AUTO_CHANGE_DELAY } from "../utils/constants.jsx";
import { parseNumber } from "../utils/parse.jsx";
import { usePressAndHold } from "../utils/use-press-and-hold.jsx";
function isTouchLikePointerType(pointerType) {
  return pointerType === "touch" || pointerType === "pen";
}
/**
 * Shared handler factory for `<NumberField.Increment>` and
 * `<NumberField.Decrement>`. Mirrors React's
 * `useNumberFieldButton` — the single press path runs `commitValue` then
 * `incrementValue`; hold starts the auto-change sequence via
 * {@link usePressAndHold}.
 */
export function useNumberFieldButton(params) {
  const pressReason = params.isIncrement ? REASONS.incrementPress : REASONS.decrementPress;
  function commitValue(nativeEvent) {
    params.allowInputSyncRef.current = true;
    const parsedValue = parseNumber(params.inputValue(), params.locale?.(), params.formatOptionsRef.current);
    if (parsedValue !== null) {
      params.valueRef.current = parsedValue;
      params.setValue(parsedValue, createChangeEventDetails(pressReason, nativeEvent, undefined, {
        direction: params.isIncrement ? 1 : -1
      }));
    }
  }
  const {
    pointerHandlers,
    shouldSkipClick
  } = usePressAndHold({
    disabled: () => params.disabled() || params.readOnly(),
    elementRef: params.inputRef,
    tickDelay: CHANGE_VALUE_TICK_DELAY,
    startDelay: START_AUTO_CHANGE_DELAY,
    scrollDistance: SCROLLING_POINTER_MOVE_DISTANCE,
    tick(triggerEvent) {
      const amount = params.getStepAmount(triggerEvent) ?? DEFAULT_STEP;
      return params.incrementValue(amount, {
        direction: params.isIncrement ? 1 : -1,
        event: triggerEvent,
        reason: pressReason
      });
    },
    onStop(nativeEvent) {
      const committed = params.lastChangedValueRef.current ?? params.valueRef.current;
      params.onValueCommitted(committed, createGenericEventDetails(pressReason, nativeEvent));
    }
  });
  const buttonProps = {
    // Seed `"aria-readonly"` with an empty string so Solid 2's DOM spread
    // keeps the key in `ownKeys` from render 1 (see
    // `test/internals/merge-props-undefined-attr.test.tsx`). `undefined`
    // collapses to "absent" via `mergePropsN`, but seeding avoids a late
    // binding issue when `readOnly` flips after render.
    get "aria-readonly"() {
      return params.readOnly() ? "true" : undefined;
    },
    "aria-label": params.isIncrement ? "Increase" : "Decrease",
    "aria-controls": params.id,
    tabIndex: -1,
    style: {
      "-webkit-user-select": "none",
      "user-select": "none"
    },
    // `touchstart` is scroll-blocking: a plain `onTouchStart` prop registers a
    // non-passive listener (Chrome perf violation). The handler only flips a
    // flag, so register it passive via Solid's `on:` namespace (a non-function
    // value is forwarded as the `addEventListener` options). `touchend` is not
    // scroll-blocking, so it stays an ordinary prop.
    "on:touchstart": {
      handleEvent: pointerHandlers.onTouchStart,
      passive: true
    },
    onTouchEnd: pointerHandlers.onTouchEnd,
    onPointerUp: pointerHandlers.onPointerUp,
    onPointerMove: pointerHandlers.onPointerMove,
    onMouseEnter: pointerHandlers.onMouseEnter,
    onMouseLeave: pointerHandlers.onMouseLeave,
    onMouseUp: pointerHandlers.onMouseUp,
    onClick(event) {
      const isDisabled = params.disabled() || params.readOnly();
      if (event.defaultPrevented || isDisabled || shouldSkipClick(event)) {
        return;
      }
      commitValue(event);
      const amount = params.getStepAmount(event) ?? DEFAULT_STEP;
      const prev = params.valueRef.current;
      params.incrementValue(amount, {
        direction: params.isIncrement ? 1 : -1,
        event,
        reason: pressReason
      });
      const committed = params.lastChangedValueRef.current ?? params.valueRef.current;
      if (committed !== prev) {
        params.onValueCommitted(committed, createGenericEventDetails(pressReason, event));
      }
    },
    onPointerDown(event) {
      const isMainButton = !event.button || event.button === 0;
      if (event.defaultPrevented || params.readOnly() || !isMainButton || params.disabled()) {
        return;
      }
      commitValue(event);
      if (!isTouchLikePointerType(event.pointerType)) {
        params.inputRef.current?.focus();
      }
      pointerHandlers.onPointerDown(event);
    }
  };
  return {
    props: buttonProps
  };
}
//# sourceMappingURL=use-number-field-button.jsx.map
