@trackunit/react-components 1.0.7 → 1.0.9

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/index.cjs.js CHANGED
@@ -290,18 +290,19 @@ const PackageNameStoryComponent = ({ packageJSON }) => {
290
290
  /**
291
291
  * Hook to detect if text content is wrapping to multiple lines
292
292
  *
293
- * @param {HTMLElement | null} element - The element to check for text wrapping
293
+ * @param {RefObject<HTMLElement>} ref - The ref to the element to check for text wrapping
294
294
  * @returns {boolean} True if the text spans multiple lines
295
295
  */
296
- const useIsTextWrapping = (element) => {
296
+ const useIsTextWrapping = (ref) => {
297
+ var _a, _b;
297
298
  const [isWrapping, setIsWrapping] = React.useState(false);
298
299
  React.useEffect(() => {
299
- if (!element) {
300
+ if (!ref.current) {
300
301
  setIsWrapping(false);
301
302
  return;
302
303
  }
303
- setIsWrapping(element.clientHeight > element.scrollHeight / 2);
304
- }, [element]);
304
+ setIsWrapping(ref.current.clientHeight > ref.current.scrollHeight / 2);
305
+ }, [(_a = ref.current) === null || _a === void 0 ? void 0 : _a.clientHeight, (_b = ref.current) === null || _b === void 0 ? void 0 : _b.scrollHeight, ref]);
305
306
  return isWrapping;
306
307
  };
307
308
 
@@ -776,7 +777,7 @@ const cvaAlertIconContainer = cssClassVarianceUtilities.cvaMerge(["self-start",
776
777
  const Alert = ({ color = "info", title, className, children, primaryAction, secondaryAction, onClose, dataTestId, autoScroll, }) => {
777
778
  const ref = React__namespace.useRef(null);
778
779
  const titleRef = React__namespace.useRef(null);
779
- const isWrapping = useIsTextWrapping(titleRef.current);
780
+ const isWrapping = useIsTextWrapping(titleRef);
780
781
  React__namespace.useEffect(() => {
781
782
  var _a, _b;
782
783
  if (autoScroll) {
@@ -1248,18 +1249,19 @@ const useIsFullscreen = () => {
1248
1249
  /**
1249
1250
  * Check if text is cut off.
1250
1251
  *
1251
- * @param {HTMLElement| null} element The element to check.
1252
+ * @param {RefObject<HTMLElement>} ref The ref to the element to check.
1252
1253
  * @returns {boolean} True if the text is cut off.
1253
1254
  */
1254
- const useIsTextCutOff = (element) => {
1255
+ const useIsTextCutOff = (ref) => {
1256
+ var _a, _b;
1255
1257
  const [isTextCutOff, setIsTextCutOff] = React.useState(false);
1256
1258
  React.useEffect(() => {
1257
- if (!element) {
1259
+ if (!ref.current) {
1258
1260
  setIsTextCutOff(false);
1259
1261
  return;
1260
1262
  }
1261
- setIsTextCutOff(element.offsetWidth < element.scrollWidth);
1262
- }, [element]);
1263
+ setIsTextCutOff(ref.current.offsetWidth < ref.current.scrollWidth);
1264
+ }, [(_a = ref.current) === null || _a === void 0 ? void 0 : _a.offsetWidth, (_b = ref.current) === null || _b === void 0 ? void 0 : _b.scrollWidth, ref]);
1263
1265
  return isTextCutOff;
1264
1266
  };
1265
1267
 
@@ -3314,6 +3316,98 @@ const ExternalLink = ({ rel = "noreferrer", target = "_blank", href, className,
3314
3316
  return (jsxRuntime.jsx("a", { className: cvaExternalLink({ className }), "data-testid": dataTestId, href: href, onClick: onClick, rel: rel, target: target, title: title, children: children }));
3315
3317
  };
3316
3318
 
3319
+ const PADDING$1 = 16;
3320
+ /**
3321
+ * Converts a width size value into a CSS dimension value for max constraints
3322
+ *
3323
+ * @param params - The parameters object
3324
+ * @param params.value - The size value: number for pixels, "trigger-width" to match trigger, "none" for no constraint
3325
+ * @param params.referenceWidth - The width of the trigger element in pixels
3326
+ * @param params.availableWidth - The available width in the viewport
3327
+ */
3328
+ const getMaxWidthValue = ({ value, referenceWidth, availableWidth }) => {
3329
+ switch (value) {
3330
+ case "trigger-width": {
3331
+ return `${referenceWidth}px`;
3332
+ }
3333
+ case undefined:
3334
+ case "none": {
3335
+ return `${availableWidth - PADDING$1 * 2}px`;
3336
+ }
3337
+ default: {
3338
+ if (typeof value === "number") {
3339
+ return `${value}px`;
3340
+ }
3341
+ throw new Error(`${value} is not known`);
3342
+ }
3343
+ }
3344
+ };
3345
+ /**
3346
+ * Converts a width size value into a CSS dimension value for min constraints
3347
+ *
3348
+ * @param params - The parameters object
3349
+ * @param params.value - The size value: number for pixels, "trigger-width" to match trigger, "none" for no constraint
3350
+ * @param params.referenceWidth - The width of the trigger element in pixels
3351
+ */
3352
+ const getMinWidthValue = ({ value, referenceWidth, }) => {
3353
+ switch (value) {
3354
+ case "trigger-width": {
3355
+ return `${referenceWidth}px`;
3356
+ }
3357
+ case undefined:
3358
+ case "none": {
3359
+ return undefined;
3360
+ }
3361
+ default: {
3362
+ if (typeof value === "number") {
3363
+ return `${value}px`;
3364
+ }
3365
+ throw new Error(`${value} is not known`);
3366
+ }
3367
+ }
3368
+ };
3369
+ /**
3370
+ * Converts a height size value into a CSS dimension value for max constraints
3371
+ *
3372
+ * @param params - The parameters object
3373
+ * @param params.value - The size value: number for pixels, "none" for no constraint
3374
+ * @param params.availableHeight - The available height in the viewport
3375
+ */
3376
+ const getMaxHeightValue = ({ value, availableHeight }) => {
3377
+ switch (value) {
3378
+ case undefined:
3379
+ case "none": {
3380
+ return `${availableHeight - PADDING$1 * 2}px`;
3381
+ }
3382
+ default: {
3383
+ if (typeof value === "number") {
3384
+ return `${value}px`;
3385
+ }
3386
+ throw new Error(`${value} is not known`);
3387
+ }
3388
+ }
3389
+ };
3390
+ /**
3391
+ * Converts a height size value into a CSS dimension value for min constraints
3392
+ *
3393
+ * @param params - The parameters object
3394
+ * @param params.value - The size value: number for pixels, "none" for no constraint
3395
+ */
3396
+ const getMinHeightValue = ({ value }) => {
3397
+ switch (value) {
3398
+ case undefined:
3399
+ case "none": {
3400
+ return undefined;
3401
+ }
3402
+ default: {
3403
+ if (typeof value === "number") {
3404
+ return `${value}px`;
3405
+ }
3406
+ throw new Error(`${value} is not known`);
3407
+ }
3408
+ }
3409
+ };
3410
+
3317
3411
  const DEFAULT_ACTIVATION = { click: true, hover: false, keyboardHandlers: true };
3318
3412
  const PADDING = 16;
3319
3413
  const DEFAULT_DISMISSAL = {
@@ -3321,14 +3415,20 @@ const DEFAULT_DISMISSAL = {
3321
3415
  outsidePress: true,
3322
3416
  ancestorScroll: false,
3323
3417
  };
3418
+ const DEFAULT_SIZING = {
3419
+ minWidth: "none",
3420
+ maxWidth: "none",
3421
+ minHeight: "none",
3422
+ maxHeight: "none",
3423
+ };
3324
3424
  /**
3325
3425
  * The hook that powers the Popover component.
3326
3426
  * It should not be used directly, but rather through the Popover component.
3327
3427
  *
3328
3428
  * @param {PopoverProps} options The options for the popover
3329
- * @returns {ReturnType<typeof usePopover>} The data for the popover
3429
+ * @returns {UsePopoverType} The data for the popover
3330
3430
  */
3331
- const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen: controlledIsOpen, activation = DEFAULT_ACTIVATION, dismissal = DEFAULT_DISMISSAL, onOpenStateChange, ...restOptions }) => {
3431
+ const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen: controlledIsOpen, activation = DEFAULT_ACTIVATION, dismissal = DEFAULT_DISMISSAL, sizing = DEFAULT_SIZING, onOpenStateChange, ...restOptions }) => {
3332
3432
  const [uncontrolledIsOpen, setUncontrolledIsOpen] = React.useState(initialOpen);
3333
3433
  const [labelId, setLabelId] = React.useState();
3334
3434
  const [descriptionId, setDescriptionId] = React.useState();
@@ -3347,9 +3447,26 @@ const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen
3347
3447
  react.shift({ padding: PADDING }),
3348
3448
  react.size({
3349
3449
  apply({ availableWidth, availableHeight, elements }) {
3350
- Object.assign(elements.floating.style, {
3351
- maxWidth: `${availableWidth - PADDING * 2}px`,
3352
- maxHeight: `${availableHeight - PADDING * 2}px`,
3450
+ const { floating, reference } = elements;
3451
+ const resolvedSizing = typeof sizing === "function" ? sizing(DEFAULT_SIZING) : sizing;
3452
+ const refRect = reference.getBoundingClientRect();
3453
+ Object.assign(floating.style, {
3454
+ maxWidth: getMaxWidthValue({
3455
+ value: resolvedSizing.maxWidth,
3456
+ referenceWidth: refRect.width,
3457
+ availableWidth,
3458
+ }),
3459
+ minWidth: getMinWidthValue({
3460
+ value: resolvedSizing.minWidth,
3461
+ referenceWidth: refRect.width,
3462
+ }),
3463
+ maxHeight: getMaxHeightValue({
3464
+ value: resolvedSizing.maxHeight,
3465
+ availableHeight,
3466
+ }),
3467
+ minHeight: getMinHeightValue({
3468
+ value: resolvedSizing.minHeight,
3469
+ }),
3353
3470
  });
3354
3471
  },
3355
3472
  }),
@@ -3422,7 +3539,9 @@ const usePopoverContext = () => {
3422
3539
  */
3423
3540
  const Popover = ({ children, isModal = false, ...restOptions }) => {
3424
3541
  const popover = usePopover({ isModal, ...restOptions });
3425
- return (jsxRuntime.jsx(PopoverContext.Provider, { value: popover, children: typeof children === "function" ? children({ isOpen: popover.isOpen, placement: popover.placement }) : children }));
3542
+ return (jsxRuntime.jsx(PopoverContext.Provider, { value: popover, children: typeof children === "function"
3543
+ ? children({ isOpen: popover.isOpen, setIsOpen: popover.setIsOpen, placement: popover.placement })
3544
+ : children }));
3426
3545
  };
3427
3546
 
3428
3547
  /** @internal */
package/index.esm.js CHANGED
@@ -270,18 +270,19 @@ const PackageNameStoryComponent = ({ packageJSON }) => {
270
270
  /**
271
271
  * Hook to detect if text content is wrapping to multiple lines
272
272
  *
273
- * @param {HTMLElement | null} element - The element to check for text wrapping
273
+ * @param {RefObject<HTMLElement>} ref - The ref to the element to check for text wrapping
274
274
  * @returns {boolean} True if the text spans multiple lines
275
275
  */
276
- const useIsTextWrapping = (element) => {
276
+ const useIsTextWrapping = (ref) => {
277
+ var _a, _b;
277
278
  const [isWrapping, setIsWrapping] = useState(false);
278
279
  useEffect(() => {
279
- if (!element) {
280
+ if (!ref.current) {
280
281
  setIsWrapping(false);
281
282
  return;
282
283
  }
283
- setIsWrapping(element.clientHeight > element.scrollHeight / 2);
284
- }, [element]);
284
+ setIsWrapping(ref.current.clientHeight > ref.current.scrollHeight / 2);
285
+ }, [(_a = ref.current) === null || _a === void 0 ? void 0 : _a.clientHeight, (_b = ref.current) === null || _b === void 0 ? void 0 : _b.scrollHeight, ref]);
285
286
  return isWrapping;
286
287
  };
287
288
 
@@ -756,7 +757,7 @@ const cvaAlertIconContainer = cvaMerge(["self-start", "shrink-0", "grid", "w-min
756
757
  const Alert = ({ color = "info", title, className, children, primaryAction, secondaryAction, onClose, dataTestId, autoScroll, }) => {
757
758
  const ref = React.useRef(null);
758
759
  const titleRef = React.useRef(null);
759
- const isWrapping = useIsTextWrapping(titleRef.current);
760
+ const isWrapping = useIsTextWrapping(titleRef);
760
761
  React.useEffect(() => {
761
762
  var _a, _b;
762
763
  if (autoScroll) {
@@ -1228,18 +1229,19 @@ const useIsFullscreen = () => {
1228
1229
  /**
1229
1230
  * Check if text is cut off.
1230
1231
  *
1231
- * @param {HTMLElement| null} element The element to check.
1232
+ * @param {RefObject<HTMLElement>} ref The ref to the element to check.
1232
1233
  * @returns {boolean} True if the text is cut off.
1233
1234
  */
1234
- const useIsTextCutOff = (element) => {
1235
+ const useIsTextCutOff = (ref) => {
1236
+ var _a, _b;
1235
1237
  const [isTextCutOff, setIsTextCutOff] = useState(false);
1236
1238
  useEffect(() => {
1237
- if (!element) {
1239
+ if (!ref.current) {
1238
1240
  setIsTextCutOff(false);
1239
1241
  return;
1240
1242
  }
1241
- setIsTextCutOff(element.offsetWidth < element.scrollWidth);
1242
- }, [element]);
1243
+ setIsTextCutOff(ref.current.offsetWidth < ref.current.scrollWidth);
1244
+ }, [(_a = ref.current) === null || _a === void 0 ? void 0 : _a.offsetWidth, (_b = ref.current) === null || _b === void 0 ? void 0 : _b.scrollWidth, ref]);
1243
1245
  return isTextCutOff;
1244
1246
  };
1245
1247
 
@@ -3294,6 +3296,98 @@ const ExternalLink = ({ rel = "noreferrer", target = "_blank", href, className,
3294
3296
  return (jsx("a", { className: cvaExternalLink({ className }), "data-testid": dataTestId, href: href, onClick: onClick, rel: rel, target: target, title: title, children: children }));
3295
3297
  };
3296
3298
 
3299
+ const PADDING$1 = 16;
3300
+ /**
3301
+ * Converts a width size value into a CSS dimension value for max constraints
3302
+ *
3303
+ * @param params - The parameters object
3304
+ * @param params.value - The size value: number for pixels, "trigger-width" to match trigger, "none" for no constraint
3305
+ * @param params.referenceWidth - The width of the trigger element in pixels
3306
+ * @param params.availableWidth - The available width in the viewport
3307
+ */
3308
+ const getMaxWidthValue = ({ value, referenceWidth, availableWidth }) => {
3309
+ switch (value) {
3310
+ case "trigger-width": {
3311
+ return `${referenceWidth}px`;
3312
+ }
3313
+ case undefined:
3314
+ case "none": {
3315
+ return `${availableWidth - PADDING$1 * 2}px`;
3316
+ }
3317
+ default: {
3318
+ if (typeof value === "number") {
3319
+ return `${value}px`;
3320
+ }
3321
+ throw new Error(`${value} is not known`);
3322
+ }
3323
+ }
3324
+ };
3325
+ /**
3326
+ * Converts a width size value into a CSS dimension value for min constraints
3327
+ *
3328
+ * @param params - The parameters object
3329
+ * @param params.value - The size value: number for pixels, "trigger-width" to match trigger, "none" for no constraint
3330
+ * @param params.referenceWidth - The width of the trigger element in pixels
3331
+ */
3332
+ const getMinWidthValue = ({ value, referenceWidth, }) => {
3333
+ switch (value) {
3334
+ case "trigger-width": {
3335
+ return `${referenceWidth}px`;
3336
+ }
3337
+ case undefined:
3338
+ case "none": {
3339
+ return undefined;
3340
+ }
3341
+ default: {
3342
+ if (typeof value === "number") {
3343
+ return `${value}px`;
3344
+ }
3345
+ throw new Error(`${value} is not known`);
3346
+ }
3347
+ }
3348
+ };
3349
+ /**
3350
+ * Converts a height size value into a CSS dimension value for max constraints
3351
+ *
3352
+ * @param params - The parameters object
3353
+ * @param params.value - The size value: number for pixels, "none" for no constraint
3354
+ * @param params.availableHeight - The available height in the viewport
3355
+ */
3356
+ const getMaxHeightValue = ({ value, availableHeight }) => {
3357
+ switch (value) {
3358
+ case undefined:
3359
+ case "none": {
3360
+ return `${availableHeight - PADDING$1 * 2}px`;
3361
+ }
3362
+ default: {
3363
+ if (typeof value === "number") {
3364
+ return `${value}px`;
3365
+ }
3366
+ throw new Error(`${value} is not known`);
3367
+ }
3368
+ }
3369
+ };
3370
+ /**
3371
+ * Converts a height size value into a CSS dimension value for min constraints
3372
+ *
3373
+ * @param params - The parameters object
3374
+ * @param params.value - The size value: number for pixels, "none" for no constraint
3375
+ */
3376
+ const getMinHeightValue = ({ value }) => {
3377
+ switch (value) {
3378
+ case undefined:
3379
+ case "none": {
3380
+ return undefined;
3381
+ }
3382
+ default: {
3383
+ if (typeof value === "number") {
3384
+ return `${value}px`;
3385
+ }
3386
+ throw new Error(`${value} is not known`);
3387
+ }
3388
+ }
3389
+ };
3390
+
3297
3391
  const DEFAULT_ACTIVATION = { click: true, hover: false, keyboardHandlers: true };
3298
3392
  const PADDING = 16;
3299
3393
  const DEFAULT_DISMISSAL = {
@@ -3301,14 +3395,20 @@ const DEFAULT_DISMISSAL = {
3301
3395
  outsidePress: true,
3302
3396
  ancestorScroll: false,
3303
3397
  };
3398
+ const DEFAULT_SIZING = {
3399
+ minWidth: "none",
3400
+ maxWidth: "none",
3401
+ minHeight: "none",
3402
+ maxHeight: "none",
3403
+ };
3304
3404
  /**
3305
3405
  * The hook that powers the Popover component.
3306
3406
  * It should not be used directly, but rather through the Popover component.
3307
3407
  *
3308
3408
  * @param {PopoverProps} options The options for the popover
3309
- * @returns {ReturnType<typeof usePopover>} The data for the popover
3409
+ * @returns {UsePopoverType} The data for the popover
3310
3410
  */
3311
- const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen: controlledIsOpen, activation = DEFAULT_ACTIVATION, dismissal = DEFAULT_DISMISSAL, onOpenStateChange, ...restOptions }) => {
3411
+ const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen: controlledIsOpen, activation = DEFAULT_ACTIVATION, dismissal = DEFAULT_DISMISSAL, sizing = DEFAULT_SIZING, onOpenStateChange, ...restOptions }) => {
3312
3412
  const [uncontrolledIsOpen, setUncontrolledIsOpen] = useState(initialOpen);
3313
3413
  const [labelId, setLabelId] = useState();
3314
3414
  const [descriptionId, setDescriptionId] = useState();
@@ -3327,9 +3427,26 @@ const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen
3327
3427
  shift({ padding: PADDING }),
3328
3428
  size({
3329
3429
  apply({ availableWidth, availableHeight, elements }) {
3330
- Object.assign(elements.floating.style, {
3331
- maxWidth: `${availableWidth - PADDING * 2}px`,
3332
- maxHeight: `${availableHeight - PADDING * 2}px`,
3430
+ const { floating, reference } = elements;
3431
+ const resolvedSizing = typeof sizing === "function" ? sizing(DEFAULT_SIZING) : sizing;
3432
+ const refRect = reference.getBoundingClientRect();
3433
+ Object.assign(floating.style, {
3434
+ maxWidth: getMaxWidthValue({
3435
+ value: resolvedSizing.maxWidth,
3436
+ referenceWidth: refRect.width,
3437
+ availableWidth,
3438
+ }),
3439
+ minWidth: getMinWidthValue({
3440
+ value: resolvedSizing.minWidth,
3441
+ referenceWidth: refRect.width,
3442
+ }),
3443
+ maxHeight: getMaxHeightValue({
3444
+ value: resolvedSizing.maxHeight,
3445
+ availableHeight,
3446
+ }),
3447
+ minHeight: getMinHeightValue({
3448
+ value: resolvedSizing.minHeight,
3449
+ }),
3333
3450
  });
3334
3451
  },
3335
3452
  }),
@@ -3402,7 +3519,9 @@ const usePopoverContext = () => {
3402
3519
  */
3403
3520
  const Popover = ({ children, isModal = false, ...restOptions }) => {
3404
3521
  const popover = usePopover({ isModal, ...restOptions });
3405
- return (jsx(PopoverContext.Provider, { value: popover, children: typeof children === "function" ? children({ isOpen: popover.isOpen, placement: popover.placement }) : children }));
3522
+ return (jsx(PopoverContext.Provider, { value: popover, children: typeof children === "function"
3523
+ ? children({ isOpen: popover.isOpen, setIsOpen: popover.setIsOpen, placement: popover.placement })
3524
+ : children }));
3406
3525
  };
3407
3526
 
3408
3527
  /** @internal */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -7,6 +7,11 @@ export type ContextType = UsePopoverType | null;
7
7
  * @returns {ContextType} The popover context
8
8
  */
9
9
  export declare const usePopoverContext: () => UsePopoverType;
10
+ type ModalCallback = {
11
+ isOpen: boolean;
12
+ setIsOpen: (isOpen: boolean) => void;
13
+ placement: PopoverPlacement;
14
+ };
10
15
  /**
11
16
  * The popover component.
12
17
  * - This component should wrap all the popover components.
@@ -21,8 +26,6 @@ export declare const usePopoverContext: () => UsePopoverType;
21
26
  * @returns {JSX.Element} A Popover Context Provider containing the children
22
27
  */
23
28
  export declare const Popover: ({ children, isModal, ...restOptions }: {
24
- children: React.ReactNode | ((modalState: {
25
- isOpen: boolean;
26
- placement: PopoverPlacement;
27
- }) => React.ReactNode);
29
+ children: React.ReactNode | ((modal: ModalCallback) => React.ReactNode);
28
30
  } & PopoverProps) => import("react/jsx-runtime").JSX.Element;
31
+ export {};
@@ -0,0 +1,44 @@
1
+ import { HeightSizeLimit, WidthSizeLimit } from "./PopoverTypes";
2
+ export declare const PADDING = 16;
3
+ type WidthValueParams = {
4
+ value: WidthSizeLimit | undefined;
5
+ referenceWidth: number;
6
+ availableWidth: number;
7
+ };
8
+ type HeightValueParams = {
9
+ value: HeightSizeLimit | undefined;
10
+ availableHeight: number;
11
+ };
12
+ /**
13
+ * Converts a width size value into a CSS dimension value for max constraints
14
+ *
15
+ * @param params - The parameters object
16
+ * @param params.value - The size value: number for pixels, "trigger-width" to match trigger, "none" for no constraint
17
+ * @param params.referenceWidth - The width of the trigger element in pixels
18
+ * @param params.availableWidth - The available width in the viewport
19
+ */
20
+ export declare const getMaxWidthValue: ({ value, referenceWidth, availableWidth }: WidthValueParams) => string;
21
+ /**
22
+ * Converts a width size value into a CSS dimension value for min constraints
23
+ *
24
+ * @param params - The parameters object
25
+ * @param params.value - The size value: number for pixels, "trigger-width" to match trigger, "none" for no constraint
26
+ * @param params.referenceWidth - The width of the trigger element in pixels
27
+ */
28
+ export declare const getMinWidthValue: ({ value, referenceWidth, }: Omit<WidthValueParams, "availableWidth">) => string | undefined;
29
+ /**
30
+ * Converts a height size value into a CSS dimension value for max constraints
31
+ *
32
+ * @param params - The parameters object
33
+ * @param params.value - The size value: number for pixels, "none" for no constraint
34
+ * @param params.availableHeight - The available height in the viewport
35
+ */
36
+ export declare const getMaxHeightValue: ({ value, availableHeight }: HeightValueParams) => string;
37
+ /**
38
+ * Converts a height size value into a CSS dimension value for min constraints
39
+ *
40
+ * @param params - The parameters object
41
+ * @param params.value - The size value: number for pixels, "none" for no constraint
42
+ */
43
+ export declare const getMinHeightValue: ({ value }: Pick<HeightValueParams, "value">) => string | undefined;
44
+ export {};
@@ -1,4 +1,5 @@
1
1
  import { ExtendedRefs, ReferenceType, UseDismissProps, UseFloatingReturn } from "@floating-ui/react";
2
+ import { Dispatch, SetStateAction } from "react";
2
3
  import { CommonProps } from "../../common";
3
4
  export type PopoverActivation = {
4
5
  click?: boolean;
@@ -8,7 +9,23 @@ export type PopoverActivation = {
8
9
  export type PopoverDismissal = Pick<UseDismissProps, "ancestorScroll" | "enabled" | "outsidePress">;
9
10
  export type PopoverPlacement = "top" | "right" | "bottom" | "left" | "top-start" | "top-end" | "right-start" | "right-end" | "bottom-start" | "bottom-end" | "left-start" | "left-end";
10
11
  export type Strategy = "absolute" | "fixed";
12
+ export type HeightSizeLimit = number | "none";
13
+ export type WidthSizeLimit = number | "trigger-width" | "none";
14
+ export type PopoverSizing = {
15
+ minWidth?: WidthSizeLimit;
16
+ maxWidth?: WidthSizeLimit;
17
+ minHeight?: HeightSizeLimit;
18
+ maxHeight?: HeightSizeLimit;
19
+ };
11
20
  export interface PopoverProps extends CommonProps {
21
+ /**
22
+ * Size constraints for the popover
23
+ * For each dimension:
24
+ * - number: explicit size in pixels
25
+ * - "trigger-width": match the trigger element's width
26
+ * - "none": let content determine size (default)
27
+ */
28
+ sizing?: PopoverSizing | ((defaultSizing: PopoverSizing) => PopoverSizing);
12
29
  /**
13
30
  * Whether the popover should be open on initial render
14
31
  */
@@ -18,7 +35,7 @@ export interface PopoverProps extends CommonProps {
18
35
  */
19
36
  placement?: PopoverPlacement;
20
37
  /**
21
- * Determines if focus is modal”, meaning focus is fully trapped inside the floating element and outside content cannot be accessed. This includes screen reader virtual cursors.
38
+ * Determines if focus is "modal", meaning focus is fully trapped inside the floating element and outside content cannot be accessed. This includes screen reader virtual cursors.
22
39
  */
23
40
  isModal?: boolean;
24
41
  /**
@@ -38,7 +55,7 @@ export interface PopoverProps extends CommonProps {
38
55
  */
39
56
  onOpenStateChange?: (open: boolean) => void;
40
57
  /**
41
- * Ihe id of the html element
58
+ * The id of the html element
42
59
  */
43
60
  id?: string;
44
61
  }
@@ -46,7 +63,7 @@ export type FloatingType = Omit<UseFloatingReturn, "middlewareData" | "floatingS
46
63
  export type ExtendedRefsType = ExtendedRefs<ReferenceType>;
47
64
  export type UsePopoverType = {
48
65
  isOpen: boolean;
49
- setIsOpen: (open: boolean) => void;
66
+ setIsOpen: Dispatch<SetStateAction<boolean>>;
50
67
  isModal: boolean | undefined;
51
68
  labelId?: string;
52
69
  descriptionId?: string;
@@ -4,6 +4,6 @@ import { PopoverProps, UsePopoverType } from "./PopoverTypes";
4
4
  * It should not be used directly, but rather through the Popover component.
5
5
  *
6
6
  * @param {PopoverProps} options The options for the popover
7
- * @returns {ReturnType<typeof usePopover>} The data for the popover
7
+ * @returns {UsePopoverType} The data for the popover
8
8
  */
9
- export declare const usePopover: ({ initialOpen, placement, isModal, isOpen: controlledIsOpen, activation, dismissal, onOpenStateChange, ...restOptions }: PopoverProps) => UsePopoverType;
9
+ export declare const usePopover: ({ initialOpen, placement, isModal, isOpen: controlledIsOpen, activation, dismissal, sizing, onOpenStateChange, ...restOptions }: PopoverProps) => UsePopoverType;
@@ -1,7 +1,8 @@
1
+ import { RefObject } from "react";
1
2
  /**
2
3
  * Check if text is cut off.
3
4
  *
4
- * @param {HTMLElement| null} element The element to check.
5
+ * @param {RefObject<HTMLElement>} ref The ref to the element to check.
5
6
  * @returns {boolean} True if the text is cut off.
6
7
  */
7
- export declare const useIsTextCutOff: (element: HTMLElement | null) => boolean;
8
+ export declare const useIsTextCutOff: (ref: RefObject<HTMLElement>) => boolean;
@@ -1,7 +1,8 @@
1
+ import { RefObject } from "react";
1
2
  /**
2
3
  * Hook to detect if text content is wrapping to multiple lines
3
4
  *
4
- * @param {HTMLElement | null} element - The element to check for text wrapping
5
+ * @param {RefObject<HTMLElement>} ref - The ref to the element to check for text wrapping
5
6
  * @returns {boolean} True if the text spans multiple lines
6
7
  */
7
- export declare const useIsTextWrapping: (element: HTMLElement | null) => boolean;
8
+ export declare const useIsTextWrapping: (ref: RefObject<HTMLElement>) => boolean;