@radix-ui/react-select 2.1.2-rc.2 → 2.1.2-rc.20

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/index.mjs CHANGED
@@ -51,7 +51,8 @@ var Select = (props) => {
51
51
  name,
52
52
  autoComplete,
53
53
  disabled,
54
- required
54
+ required,
55
+ form
55
56
  } = props;
56
57
  const popperScope = usePopperScope(__scopeSelect);
57
58
  const [trigger, setTrigger] = React.useState(null);
@@ -69,7 +70,7 @@ var Select = (props) => {
69
70
  onChange: onValueChange
70
71
  });
71
72
  const triggerPointerDownPosRef = React.useRef(null);
72
- const isFormControl = trigger ? Boolean(trigger.closest("form")) : true;
73
+ const isFormControl = trigger ? Boolean(trigger.closest("form")) || form : true;
73
74
  const [nativeOptionsSet, setNativeOptionsSet] = React.useState(/* @__PURE__ */ new Set());
74
75
  const nativeSelectKey = Array.from(nativeOptionsSet).map((option) => option.props.value).join(";");
75
76
  return /* @__PURE__ */ jsx(PopperPrimitive.Root, { ...popperScope, children: /* @__PURE__ */ jsxs(
@@ -120,6 +121,7 @@ var Select = (props) => {
120
121
  value,
121
122
  onChange: (event) => setValue(event.target.value),
122
123
  disabled,
124
+ form,
123
125
  children: [
124
126
  value === void 0 ? /* @__PURE__ */ jsx("option", { value: "" }) : null,
125
127
  Array.from(nativeOptionsSet)
@@ -141,6 +143,7 @@ var SelectTrigger = React.forwardRef(
141
143
  const isDisabled = context.disabled || disabled;
142
144
  const composedRefs = useComposedRefs(forwardedRef, context.onTriggerChange);
143
145
  const getItems = useCollection(__scopeSelect);
146
+ const pointerTypeRef = React.useRef("touch");
144
147
  const [searchRef, handleTypeaheadSearch, resetTypeahead] = useTypeaheadSearch((search) => {
145
148
  const enabledItems = getItems().filter((item) => !item.disabled);
146
149
  const currentItem = enabledItems.find((item) => item.value === context.value);
@@ -149,11 +152,17 @@ var SelectTrigger = React.forwardRef(
149
152
  context.onValueChange(nextItem.value);
150
153
  }
151
154
  });
152
- const handleOpen = () => {
155
+ const handleOpen = (pointerEvent) => {
153
156
  if (!isDisabled) {
154
157
  context.onOpenChange(true);
155
158
  resetTypeahead();
156
159
  }
160
+ if (pointerEvent) {
161
+ context.triggerPointerDownPosRef.current = {
162
+ x: Math.round(pointerEvent.pageX),
163
+ y: Math.round(pointerEvent.pageY)
164
+ };
165
+ }
157
166
  };
158
167
  return /* @__PURE__ */ jsx(PopperPrimitive.Anchor, { asChild: true, ...popperScope, children: /* @__PURE__ */ jsx(
159
168
  Primitive.button,
@@ -173,18 +182,18 @@ var SelectTrigger = React.forwardRef(
173
182
  ref: composedRefs,
174
183
  onClick: composeEventHandlers(triggerProps.onClick, (event) => {
175
184
  event.currentTarget.focus();
185
+ if (pointerTypeRef.current !== "mouse") {
186
+ handleOpen(event);
187
+ }
176
188
  }),
177
189
  onPointerDown: composeEventHandlers(triggerProps.onPointerDown, (event) => {
190
+ pointerTypeRef.current = event.pointerType;
178
191
  const target = event.target;
179
192
  if (target.hasPointerCapture(event.pointerId)) {
180
193
  target.releasePointerCapture(event.pointerId);
181
194
  }
182
- if (event.button === 0 && event.ctrlKey === false) {
183
- handleOpen();
184
- context.triggerPointerDownPosRef.current = {
185
- x: Math.round(event.pageX),
186
- y: Math.round(event.pageY)
187
- };
195
+ if (event.button === 0 && event.ctrlKey === false && event.pointerType === "mouse") {
196
+ handleOpen(event);
188
197
  event.preventDefault();
189
198
  }
190
199
  }),
@@ -519,7 +528,15 @@ var SelectItemAlignedPosition = React.forwardRef((props, forwardedRef) => {
519
528
  const minContentWidth = triggerRect.width + leftDelta;
520
529
  const contentWidth = Math.max(minContentWidth, contentRect.width);
521
530
  const rightEdge = window.innerWidth - CONTENT_MARGIN;
522
- const clampedLeft = clamp(left, [CONTENT_MARGIN, rightEdge - contentWidth]);
531
+ const clampedLeft = clamp(left, [
532
+ CONTENT_MARGIN,
533
+ // Prevents the content from going off the starting edge of the
534
+ // viewport. It may still go off the ending edge, but this can be
535
+ // controlled by the user since they may want to manage overflow in a
536
+ // specific way.
537
+ // https://github.com/radix-ui/primitives/issues/2049
538
+ Math.max(CONTENT_MARGIN, rightEdge - contentWidth)
539
+ ]);
523
540
  contentWrapper.style.minWidth = minContentWidth + "px";
524
541
  contentWrapper.style.left = clampedLeft + "px";
525
542
  } else {
@@ -529,7 +546,10 @@ var SelectItemAlignedPosition = React.forwardRef((props, forwardedRef) => {
529
546
  const minContentWidth = triggerRect.width + rightDelta;
530
547
  const contentWidth = Math.max(minContentWidth, contentRect.width);
531
548
  const leftEdge = window.innerWidth - CONTENT_MARGIN;
532
- const clampedRight = clamp(right, [CONTENT_MARGIN, leftEdge - contentWidth]);
549
+ const clampedRight = clamp(right, [
550
+ CONTENT_MARGIN,
551
+ Math.max(CONTENT_MARGIN, leftEdge - contentWidth)
552
+ ]);
533
553
  contentWrapper.style.minWidth = minContentWidth + "px";
534
554
  contentWrapper.style.right = clampedRight + "px";
535
555
  }
@@ -713,7 +733,11 @@ var SelectViewport = React.forwardRef(
713
733
  // (independent of the scrollUpButton).
714
734
  position: "relative",
715
735
  flex: 1,
716
- overflow: "auto",
736
+ // Viewport should only be scrollable in the vertical direction.
737
+ // This won't work in vertical writing modes, so we'll need to
738
+ // revisit this if/when that is supported
739
+ // https://developer.chrome.com/blog/vertical-form-controls
740
+ overflow: "hidden auto",
717
741
  ...viewportProps.style
718
742
  },
719
743
  onScroll: composeEventHandlers(viewportProps.onScroll, (event) => {
@@ -786,6 +810,7 @@ var SelectItem = React.forwardRef(
786
810
  (node) => contentContext.itemRefCallback?.(node, value, disabled)
787
811
  );
788
812
  const textId = useId();
813
+ const pointerTypeRef = React.useRef("touch");
789
814
  const handleSelect = () => {
790
815
  if (!disabled) {
791
816
  context.onValueChange(value);
@@ -830,11 +855,20 @@ var SelectItem = React.forwardRef(
830
855
  ref: composedRefs,
831
856
  onFocus: composeEventHandlers(itemProps.onFocus, () => setIsFocused(true)),
832
857
  onBlur: composeEventHandlers(itemProps.onBlur, () => setIsFocused(false)),
833
- onPointerUp: composeEventHandlers(itemProps.onPointerUp, handleSelect),
858
+ onClick: composeEventHandlers(itemProps.onClick, () => {
859
+ if (pointerTypeRef.current !== "mouse") handleSelect();
860
+ }),
861
+ onPointerUp: composeEventHandlers(itemProps.onPointerUp, () => {
862
+ if (pointerTypeRef.current === "mouse") handleSelect();
863
+ }),
864
+ onPointerDown: composeEventHandlers(itemProps.onPointerDown, (event) => {
865
+ pointerTypeRef.current = event.pointerType;
866
+ }),
834
867
  onPointerMove: composeEventHandlers(itemProps.onPointerMove, (event) => {
868
+ pointerTypeRef.current = event.pointerType;
835
869
  if (disabled) {
836
870
  contentContext.onItemLeave?.();
837
- } else {
871
+ } else if (pointerTypeRef.current === "mouse") {
838
872
  event.currentTarget.focus({ preventScroll: true });
839
873
  }
840
874
  }),