@hexdspace/react 0.1.31 → 0.1.33

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.
Files changed (2) hide show
  1. package/dist/index.js +46 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2849,6 +2849,24 @@ function useWindowTimeout() {
2849
2849
  React13.useEffect(() => clear, [clear]);
2850
2850
  return { set, clear };
2851
2851
  }
2852
+ function getFocusableElements() {
2853
+ const selector = [
2854
+ "a[href]",
2855
+ "button:not([disabled])",
2856
+ "textarea:not([disabled])",
2857
+ "input:not([disabled])",
2858
+ "select:not([disabled])",
2859
+ '[tabindex]:not([tabindex="-1"])'
2860
+ ].join(",");
2861
+ return Array.from(document.querySelectorAll(selector));
2862
+ }
2863
+ function getNextFocusableElement(currentElement, reverse = false) {
2864
+ const focusableElements = getFocusableElements();
2865
+ const currentIndex = focusableElements.indexOf(currentElement);
2866
+ if (currentIndex === -1) return null;
2867
+ const nextIndex = reverse ? currentIndex - 1 : currentIndex + 1;
2868
+ return focusableElements[nextIndex] || null;
2869
+ }
2852
2870
  function DropdownMenu({
2853
2871
  trigger,
2854
2872
  children,
@@ -2924,15 +2942,37 @@ function DropdownMenu({
2924
2942
  triggerProps.onKeyDown?.(event);
2925
2943
  lastInputRef.current = "keyboard";
2926
2944
  }
2927
- }) : trigger;
2945
+ }) : React13.cloneElement(triggerElement, {
2946
+ ref: composedTriggerRef
2947
+ });
2928
2948
  const contentPropsWithRef = contentProps;
2929
2949
  const {
2930
2950
  className: contentClassName,
2931
2951
  style: contentStyle,
2932
2952
  ref: contentPropRef,
2953
+ onKeyDown: userOnKeyDown,
2933
2954
  ...restContentProps
2934
2955
  } = contentPropsWithRef ?? {};
2935
2956
  const composedContentRef = useComposedRefs(contentRef, contentPropRef);
2957
+ const handleContentKeyDown = React13.useCallback(
2958
+ (event) => {
2959
+ userOnKeyDown?.(event);
2960
+ if (event.key === "Tab" && !event.defaultPrevented) {
2961
+ event.preventDefault();
2962
+ const triggerElement2 = triggerRef.current;
2963
+ if (!triggerElement2) return;
2964
+ const reverse = event.shiftKey;
2965
+ const nextElement = getNextFocusableElement(triggerElement2, reverse);
2966
+ handleOpenChange(false);
2967
+ if (nextElement) {
2968
+ setTimeout(() => {
2969
+ nextElement.focus();
2970
+ }, 0);
2971
+ }
2972
+ }
2973
+ },
2974
+ [handleOpenChange, userOnKeyDown]
2975
+ );
2936
2976
  const onPointerDownOutside = (event) => {
2937
2977
  restContentProps.onPointerDownOutside?.(event);
2938
2978
  };
@@ -2941,6 +2981,7 @@ function DropdownMenu({
2941
2981
  };
2942
2982
  const resolvedContentProps = hoverOpen ? {
2943
2983
  ...restContentProps,
2984
+ onKeyDown: handleContentKeyDown,
2944
2985
  onPointerEnter: (event) => {
2945
2986
  restContentProps.onPointerEnter?.(event);
2946
2987
  closeTimer.clear();
@@ -2956,7 +2997,10 @@ function DropdownMenu({
2956
2997
  },
2957
2998
  onPointerDownOutside,
2958
2999
  onInteractOutside
2959
- } : restContentProps;
3000
+ } : {
3001
+ ...restContentProps,
3002
+ onKeyDown: handleContentKeyDown
3003
+ };
2960
3004
  return /* @__PURE__ */ jsxs11(DropdownMenuPrimitive.Root, { open: resolvedOpen, onOpenChange: handleOpenChange, modal, children: [
2961
3005
  /* @__PURE__ */ jsx19(DropdownMenuPrimitive.Trigger, { asChild: true, children: resolvedTrigger }),
2962
3006
  /* @__PURE__ */ jsx19(DropdownMenuPrimitive.Portal, { forceMount: true, container: portalContainer, children: /* @__PURE__ */ jsx19(AnimatePresence4, { children: resolvedOpen ? /* @__PURE__ */ jsx19(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hexdspace/react",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",