@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 +136 -17
- package/index.esm.js +136 -17
- package/package.json +1 -1
- package/src/components/Popover/Popover.d.ts +7 -4
- package/src/components/Popover/PopoverSizing.d.ts +44 -0
- package/src/components/Popover/PopoverTypes.d.ts +20 -3
- package/src/components/Popover/usePopover.d.ts +2 -2
- package/src/hooks/useIsTextCutOff.d.ts +3 -2
- package/src/hooks/useIsTextWrapping.d.ts +3 -2
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
|
|
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 = (
|
|
296
|
+
const useIsTextWrapping = (ref) => {
|
|
297
|
+
var _a, _b;
|
|
297
298
|
const [isWrapping, setIsWrapping] = React.useState(false);
|
|
298
299
|
React.useEffect(() => {
|
|
299
|
-
if (!
|
|
300
|
+
if (!ref.current) {
|
|
300
301
|
setIsWrapping(false);
|
|
301
302
|
return;
|
|
302
303
|
}
|
|
303
|
-
setIsWrapping(
|
|
304
|
-
}, [
|
|
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
|
|
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
|
|
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 = (
|
|
1255
|
+
const useIsTextCutOff = (ref) => {
|
|
1256
|
+
var _a, _b;
|
|
1255
1257
|
const [isTextCutOff, setIsTextCutOff] = React.useState(false);
|
|
1256
1258
|
React.useEffect(() => {
|
|
1257
|
-
if (!
|
|
1259
|
+
if (!ref.current) {
|
|
1258
1260
|
setIsTextCutOff(false);
|
|
1259
1261
|
return;
|
|
1260
1262
|
}
|
|
1261
|
-
setIsTextCutOff(
|
|
1262
|
-
}, [
|
|
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 {
|
|
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
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
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"
|
|
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
|
|
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 = (
|
|
276
|
+
const useIsTextWrapping = (ref) => {
|
|
277
|
+
var _a, _b;
|
|
277
278
|
const [isWrapping, setIsWrapping] = useState(false);
|
|
278
279
|
useEffect(() => {
|
|
279
|
-
if (!
|
|
280
|
+
if (!ref.current) {
|
|
280
281
|
setIsWrapping(false);
|
|
281
282
|
return;
|
|
282
283
|
}
|
|
283
|
-
setIsWrapping(
|
|
284
|
-
}, [
|
|
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
|
|
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
|
|
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 = (
|
|
1235
|
+
const useIsTextCutOff = (ref) => {
|
|
1236
|
+
var _a, _b;
|
|
1235
1237
|
const [isTextCutOff, setIsTextCutOff] = useState(false);
|
|
1236
1238
|
useEffect(() => {
|
|
1237
|
-
if (!
|
|
1239
|
+
if (!ref.current) {
|
|
1238
1240
|
setIsTextCutOff(false);
|
|
1239
1241
|
return;
|
|
1240
1242
|
}
|
|
1241
|
-
setIsTextCutOff(
|
|
1242
|
-
}, [
|
|
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 {
|
|
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
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
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"
|
|
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
|
@@ -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 | ((
|
|
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
|
|
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
|
-
*
|
|
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:
|
|
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 {
|
|
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
|
|
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: (
|
|
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
|
|
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: (
|
|
8
|
+
export declare const useIsTextWrapping: (ref: RefObject<HTMLElement>) => boolean;
|