@pushwoosh/dumb-components 1.1.156 → 1.1.158

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.
@@ -22,7 +22,8 @@ function FreeCombobox({
22
22
  autosize,
23
23
  hasError,
24
24
  width,
25
- minWidth
25
+ minWidth,
26
+ fullWidth
26
27
  }) {
27
28
  const inputRef = useRef(null);
28
29
  const baseId = useId();
@@ -110,6 +111,7 @@ function FreeCombobox({
110
111
  width: width,
111
112
  minWidth: minWidth,
112
113
  autosize: autosize,
114
+ fullWidth: fullWidth,
113
115
  onShellMouseDown: onShellMouseDown,
114
116
  onClose: close,
115
117
  showClear: !!(clearable && value),
@@ -165,7 +167,8 @@ function SelectCombobox({
165
167
  autosize,
166
168
  hasError,
167
169
  width,
168
- minWidth
170
+ minWidth,
171
+ fullWidth
169
172
  }) {
170
173
  const inputRef = useRef(null);
171
174
  const baseId = useId();
@@ -258,6 +261,7 @@ function SelectCombobox({
258
261
  width: width,
259
262
  minWidth: minWidth,
260
263
  autosize: autosize,
264
+ fullWidth: fullWidth,
261
265
  onShellMouseDown: onShellMouseDown,
262
266
  onClose: close,
263
267
  showClear: !!(clearable && hasValue),
@@ -54,6 +54,8 @@ type CommonProps<T> = {
54
54
  width?: string;
55
55
  /** Minimum CSS width, useful together with `autosize`. */
56
56
  minWidth?: string;
57
+ /** Let the dropdown stretch to the field width instead of capping at the default width (use for wide, full-width fields). */
58
+ fullWidth?: boolean;
57
59
  };
58
60
  /**
59
61
  * Free-text Combobox: the value is the typed string and `items`/`loadItems`
@@ -13,4 +13,4 @@ import { type ComboboxMultiProps } from './types';
13
13
  * creatable
14
14
  * />
15
15
  */
16
- export declare function ComboboxMulti<T>({ items, loadItems, debounceMs, minChars, value, onChange, onClose, autoFocus, getLabel, getKey: getKeyProp, filter, renderItem, emptyText, loadingText, creatable, onCreate, canCreate, renderCreateLabel, maxValues, placeholder, disabled, loading, clearable, autosize, hasError, width, minWidth, }: ComboboxMultiProps<T>): ReactElement;
16
+ export declare function ComboboxMulti<T>({ items, loadItems, debounceMs, minChars, value, onChange, onClose, autoFocus, getLabel, getKey: getKeyProp, filter, renderItem, emptyText, loadingText, creatable, onCreate, canCreate, renderCreateLabel, maxValues, placeholder, disabled, loading, clearable, autosize, hasError, width, minWidth, fullWidth, }: ComboboxMultiProps<T>): ReactElement;
@@ -48,7 +48,8 @@ export function ComboboxMulti({
48
48
  autosize,
49
49
  hasError,
50
50
  width,
51
- minWidth
51
+ minWidth,
52
+ fullWidth
52
53
  }) {
53
54
  const inputRef = useRef(null);
54
55
  const isAsync = !!loadItems;
@@ -180,6 +181,7 @@ export function ComboboxMulti({
180
181
  width: width,
181
182
  minWidth: minWidth,
182
183
  autosize: autosize,
184
+ fullWidth: fullWidth,
183
185
  tightLeft: hasTags,
184
186
  onShellMouseDown: onShellMouseDown,
185
187
  onClose: close,
@@ -57,5 +57,7 @@ export type ComboboxMultiProps<T> = ItemsSource<T> & GetKeyProp<T> & CreatablePr
57
57
  width?: string;
58
58
  /** Minimum CSS width, useful together with `autosize`. */
59
59
  minWidth?: string;
60
+ /** Let the dropdown stretch to the field width instead of capping at the default width (use for wide, full-width fields). */
61
+ fullWidth?: boolean;
60
62
  };
61
63
  export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Resolve `arrowOffset` to a px gap. Accepts a number, or a numeric string like `'20px'`
3
+ * (only the leading number is used, the unit is ignored); anything unparseable falls back
4
+ * to the default.
5
+ */
6
+ export declare function resolveArrowPadding(arrowOffset: number | string | undefined): number;
@@ -0,0 +1,18 @@
1
+ import { DEFAULT_ARROW_PADDING } from './constants';
2
+ /**
3
+ * Resolve `arrowOffset` to a px gap. Accepts a number, or a numeric string like `'20px'`
4
+ * (only the leading number is used, the unit is ignored); anything unparseable falls back
5
+ * to the default.
6
+ */
7
+ export function resolveArrowPadding(arrowOffset) {
8
+ if (typeof arrowOffset === 'number') {
9
+ return arrowOffset;
10
+ }
11
+ if (typeof arrowOffset === 'string') {
12
+ const parsed = parseFloat(arrowOffset);
13
+ if (Number.isFinite(parsed)) {
14
+ return parsed;
15
+ }
16
+ }
17
+ return DEFAULT_ARROW_PADDING;
18
+ }
@@ -9,8 +9,8 @@ export type TooltipProps = {
9
9
  readonly position?: TooltipPosition;
10
10
  /** `[skidding, distance]` offset from the anchor; defaults per position. */
11
11
  readonly offset?: [number, number];
12
- /** Min gap (px) the arrow keeps from the tooltip corners; arrow points at the anchor (default `12`). */
13
- readonly arrowOffset?: string;
12
+ /** Min gap the arrow keeps from tooltip corners: a number or numeric string like `'20px'` — unit ignored, treated as px (default `12`). */
13
+ readonly arrowOffset?: number | string;
14
14
  /** Max width in pixels, or `'none'` (default `240`). */
15
15
  readonly maxWidth?: number | 'none';
16
16
  /** Stacking z-index. */
@@ -3,7 +3,7 @@ import type { TooltipPosition } from './types';
3
3
  type Args = {
4
4
  position: TooltipPosition;
5
5
  offset?: [number, number] | undefined;
6
- arrowOffset?: string | undefined;
6
+ arrowOffset?: number | string | undefined;
7
7
  isOpen: boolean;
8
8
  };
9
9
  /**
@@ -1,6 +1,6 @@
1
1
  import { arrow, autoUpdate, flip, offset, shift, useFloating } from '@floating-ui/react-dom';
2
2
  import { useRef } from 'react';
3
- import { DEFAULT_ARROW_PADDING } from './constants';
3
+ import { resolveArrowPadding } from './helpers';
4
4
  import { TooltipPositionToFloatingPlacementMap, TooltipPositionToOffsetMap } from './maps';
5
5
  const ArrowStaticSideMap = {
6
6
  top: 'bottom',
@@ -22,8 +22,7 @@ export function useTooltipPosition({
22
22
  }) {
23
23
  const arrowRef = useRef(null);
24
24
  const [skidding, distance] = offsetProp ?? TooltipPositionToOffsetMap[position];
25
- const parsedPadding = arrowOffset != null ? parseFloat(arrowOffset) : NaN;
26
- const arrowPadding = Number.isFinite(parsedPadding) ? parsedPadding : DEFAULT_ARROW_PADDING;
25
+ const arrowPadding = resolveArrowPadding(arrowOffset);
27
26
  const {
28
27
  refs,
29
28
  floatingStyles,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushwoosh/dumb-components",
3
- "version": "1.1.156",
3
+ "version": "1.1.158",
4
4
  "description": "React components to build Pushwoosh products",
5
5
  "main": "index.js",
6
6
  "module": "index.js",
@@ -10,6 +10,7 @@ type FieldShellProps = {
10
10
  width?: string;
11
11
  minWidth?: string;
12
12
  autosize?: boolean;
13
+ fullWidth?: boolean;
13
14
  tightLeft?: boolean;
14
15
  onShellMouseDown?: (event: MouseEvent<HTMLDivElement>) => void;
15
16
  onClose?: () => void;
@@ -33,5 +34,5 @@ type FieldShellProps = {
33
34
  * Internal field wrapper shared by the Combobox family: renders the input area with
34
35
  * its border/error/loading states and hosts the {@link SuggestionsDropdown}.
35
36
  */
36
- export declare function FieldShell({ children, isOpen, dropdownOpen, isErrored, disabled, loading, width, minWidth, autosize, tightLeft, onShellMouseDown, onClose, showClear, onClear, clearLabel, showChevron, onToggle, dropdownItems, emptyText, loadingText, loadingMore, onLoadMore, createLabel, createActive, onCreate, listboxId, createId, }: FieldShellProps): ReactElement;
37
+ export declare function FieldShell({ children, isOpen, dropdownOpen, isErrored, disabled, loading, width, minWidth, autosize, fullWidth, tightLeft, onShellMouseDown, onClose, showClear, onClear, clearLabel, showChevron, onToggle, dropdownItems, emptyText, loadingText, loadingMore, onLoadMore, createLabel, createActive, onCreate, listboxId, createId, }: FieldShellProps): ReactElement;
37
38
  export {};
@@ -18,6 +18,7 @@ export function FieldShell({
18
18
  width,
19
19
  minWidth,
20
20
  autosize,
21
+ fullWidth,
21
22
  tightLeft,
22
23
  onShellMouseDown,
23
24
  onClose,
@@ -44,7 +45,8 @@ export function FieldShell({
44
45
  floatingStyles
45
46
  } = useDropdownPosition({
46
47
  isOpen: dropdownOpen,
47
- onClickOutside: onClose
48
+ onClickOutside: onClose,
49
+ fullWidth
48
50
  });
49
51
  const {
50
52
  zIndex
@@ -2,6 +2,7 @@ import { Color } from '@pushwoosh/kit-constants';
2
2
  export declare const LOADING_BORDER_COLORS: readonly [Color.PRIMARY, Color.BRIGHT, Color.BRAND_GREEN, Color.EXCEPTIONAL];
3
3
  export declare const LOADING_BORDER_ANIMATION_MS = 3000;
4
4
  export declare const DROPDOWN_MAX_HEIGHT = 280;
5
- export declare const DROPDOWN_MAX_WIDTH = 320;
5
+ /** Default dropdown width cap. A field wider than this stretches the dropdown to its own width only when the field opts in via `fullWidth`; otherwise the dropdown stays capped here. */
6
+ export declare const DROPDOWN_DEFAULT_WIDTH = 320;
6
7
  /** Default debounce (ms) before an async `loadItems` call fires after the query changes. */
7
8
  export declare const DEFAULT_DEBOUNCE_MS = 250;
@@ -2,6 +2,7 @@ import { Color } from '@pushwoosh/kit-constants';
2
2
  export const LOADING_BORDER_COLORS = [Color.PRIMARY, Color.BRIGHT, Color.BRAND_GREEN, Color.EXCEPTIONAL];
3
3
  export const LOADING_BORDER_ANIMATION_MS = 3000;
4
4
  export const DROPDOWN_MAX_HEIGHT = 280;
5
- export const DROPDOWN_MAX_WIDTH = 320;
5
+ /** Default dropdown width cap. A field wider than this stretches the dropdown to its own width only when the field opts in via `fullWidth`; otherwise the dropdown stays capped here. */
6
+ export const DROPDOWN_DEFAULT_WIDTH = 320;
6
7
  /** Default debounce (ms) before an async `loadItems` call fires after the query changes. */
7
8
  export const DEFAULT_DEBOUNCE_MS = 250;
@@ -1,12 +1,15 @@
1
1
  type Args = {
2
2
  isOpen?: boolean;
3
3
  onClickOutside?: () => void;
4
+ fullWidth?: boolean;
4
5
  };
5
6
  /**
6
7
  * Positions the dropdown relative to the field via floating-ui (flip, offset,
7
- * width/height sizing) and wires click-outside to `onClickOutside`.
8
+ * width/height sizing) and wires click-outside to `onClickOutside`. With
9
+ * `fullWidth` the dropdown stretches to the field width instead of capping at
10
+ * `DROPDOWN_DEFAULT_WIDTH`.
8
11
  */
9
- export declare function useDropdownPosition({ isOpen, onClickOutside }: Args): {
12
+ export declare function useDropdownPosition({ isOpen, onClickOutside, fullWidth }: Args): {
10
13
  setReference: (node: import("@floating-ui/react-dom").ReferenceType | null) => void;
11
14
  setFloating: (node: HTMLElement | null) => void;
12
15
  floatingRef: import("react").MutableRefObject<HTMLElement | null>;
@@ -1,13 +1,16 @@
1
1
  import { autoUpdate, flip, offset, size, useFloating } from '@floating-ui/react-dom';
2
- import { DROPDOWN_MAX_WIDTH } from './constants';
2
+ import { DROPDOWN_DEFAULT_WIDTH } from './constants';
3
3
  import { useOnClickOutside } from '../../hooks';
4
4
  /**
5
5
  * Positions the dropdown relative to the field via floating-ui (flip, offset,
6
- * width/height sizing) and wires click-outside to `onClickOutside`.
6
+ * width/height sizing) and wires click-outside to `onClickOutside`. With
7
+ * `fullWidth` the dropdown stretches to the field width instead of capping at
8
+ * `DROPDOWN_DEFAULT_WIDTH`.
7
9
  */
8
10
  export function useDropdownPosition({
9
11
  isOpen,
10
- onClickOutside
12
+ onClickOutside,
13
+ fullWidth
11
14
  }) {
12
15
  const {
13
16
  refs,
@@ -23,9 +26,11 @@ export function useDropdownPosition({
23
26
  availableWidth,
24
27
  availableHeight
25
28
  }) {
26
- const maxWidth = Math.min(DROPDOWN_MAX_WIDTH, availableWidth);
29
+ const fieldWidth = rects.reference.width;
30
+ const maxWidth = fullWidth ? Math.min(Math.max(fieldWidth, DROPDOWN_DEFAULT_WIDTH), availableWidth) : Math.min(DROPDOWN_DEFAULT_WIDTH, availableWidth);
31
+ const minWidth = Math.min(fieldWidth, maxWidth);
27
32
  Object.assign(elements.floating.style, {
28
- minWidth: `${Math.min(rects.reference.width, maxWidth)}px`,
33
+ minWidth: `${minWidth}px`,
29
34
  maxWidth: `${maxWidth}px`,
30
35
  maxHeight: `${Math.max(0, availableHeight - 8)}px`
31
36
  });