@simplybusiness/mobius 10.4.2 → 10.4.4
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/CHANGELOG.md +17 -0
- package/dist/cjs/components/AddressLookup/AddressLookup.js +39 -36
- package/dist/cjs/components/AddressLookup/AddressLookup.js.map +3 -3
- package/dist/cjs/components/AddressLookup/index.js +39 -36
- package/dist/cjs/components/AddressLookup/index.js.map +3 -3
- package/dist/cjs/components/Breadcrumbs/Breadcrumbs.js +3 -7
- package/dist/cjs/components/Breadcrumbs/Breadcrumbs.js.map +2 -2
- package/dist/cjs/components/Breadcrumbs/index.js +3 -7
- package/dist/cjs/components/Breadcrumbs/index.js.map +2 -2
- package/dist/cjs/components/Combobox/Combobox.js +35 -32
- package/dist/cjs/components/Combobox/Combobox.js.map +3 -3
- package/dist/cjs/components/Combobox/index.js +35 -32
- package/dist/cjs/components/Combobox/index.js.map +3 -3
- package/dist/cjs/components/DateField/DateField.js +11 -8
- package/dist/cjs/components/DateField/DateField.js.map +3 -3
- package/dist/cjs/components/DateField/index.js +11 -8
- package/dist/cjs/components/DateField/index.js.map +3 -3
- package/dist/cjs/components/DropdownMenu/Item.js +3 -6
- package/dist/cjs/components/DropdownMenu/Item.js.map +2 -2
- package/dist/cjs/components/DropdownMenu/index.js +3 -6
- package/dist/cjs/components/DropdownMenu/index.js.map +2 -2
- package/dist/cjs/components/MaskedField/MaskedField.js +11 -8
- package/dist/cjs/components/MaskedField/MaskedField.js.map +3 -3
- package/dist/cjs/components/MaskedField/index.js +13 -10
- package/dist/cjs/components/MaskedField/index.js.map +3 -3
- package/dist/cjs/components/NumberField/NumberField.js +10 -7
- package/dist/cjs/components/NumberField/NumberField.js.map +3 -3
- package/dist/cjs/components/NumberField/index.js +10 -7
- package/dist/cjs/components/NumberField/index.js.map +3 -3
- package/dist/cjs/components/PasswordField/PasswordField.js +9 -6
- package/dist/cjs/components/PasswordField/PasswordField.js.map +3 -3
- package/dist/cjs/components/PasswordField/index.js +9 -6
- package/dist/cjs/components/PasswordField/index.js.map +3 -3
- package/dist/cjs/components/Popover/Arrow.js +43 -0
- package/dist/cjs/components/Popover/Arrow.js.map +7 -0
- package/dist/cjs/components/Popover/Popover.js +258 -83
- package/dist/cjs/components/Popover/Popover.js.map +4 -4
- package/dist/cjs/components/Popover/index.js +258 -83
- package/dist/cjs/components/Popover/index.js.map +4 -4
- package/dist/cjs/components/Popover/useAutoUpdate.js +53 -0
- package/dist/cjs/components/Popover/useAutoUpdate.js.map +7 -0
- package/dist/cjs/components/Popover/useFloatingPosition.js +128 -0
- package/dist/cjs/components/Popover/useFloatingPosition.js.map +7 -0
- package/dist/cjs/components/Popover/useOutsidePress.js +46 -0
- package/dist/cjs/components/Popover/useOutsidePress.js.map +7 -0
- package/dist/cjs/components/TextField/TextField.js +6 -3
- package/dist/cjs/components/TextField/TextField.js.map +3 -3
- package/dist/cjs/components/TextField/adornmentWithClassName.js +3 -2
- package/dist/cjs/components/TextField/adornmentWithClassName.js.map +2 -2
- package/dist/cjs/components/TextField/index.js +6 -3
- package/dist/cjs/components/TextField/index.js.map +3 -3
- package/dist/cjs/components/index.js +550 -377
- package/dist/cjs/components/index.js.map +4 -4
- package/dist/cjs/index.js +550 -377
- package/dist/cjs/index.js.map +4 -4
- package/dist/cjs/meta.json +490 -121
- package/dist/esm/chunk-26KZYRE6.js +108 -0
- package/dist/esm/chunk-26KZYRE6.js.map +7 -0
- package/dist/esm/{chunk-XNEQHHNV.js → chunk-5QMKPWB4.js} +2 -2
- package/dist/esm/{chunk-IQKS662C.js → chunk-6RDK3FM2.js} +5 -3
- package/dist/esm/chunk-6RDK3FM2.js.map +7 -0
- package/dist/esm/{chunk-4HI2AOBC.js → chunk-6TSYA7CJ.js} +4 -7
- package/dist/esm/{chunk-4HI2AOBC.js.map → chunk-6TSYA7CJ.js.map} +2 -2
- package/dist/esm/chunk-CAL44W47.js +23 -0
- package/dist/esm/chunk-CAL44W47.js.map +7 -0
- package/dist/esm/{chunk-PEEQNAIN.js → chunk-DMYDWKKA.js} +4 -4
- package/dist/esm/{chunk-IM3I5CZL.js → chunk-I6CFRGID.js} +4 -3
- package/dist/esm/{chunk-IM3I5CZL.js.map → chunk-I6CFRGID.js.map} +2 -2
- package/dist/esm/chunk-K3ECDAUR.js +33 -0
- package/dist/esm/chunk-K3ECDAUR.js.map +7 -0
- package/dist/esm/{chunk-GJBH37DH.js → chunk-KFHPI67N.js} +4 -4
- package/dist/esm/{chunk-OEDU5ZEA.js → chunk-KUH5AB5T.js} +2 -2
- package/dist/esm/{chunk-JFDDW3IV.js → chunk-P7TPNRU4.js} +4 -8
- package/dist/esm/{chunk-JFDDW3IV.js.map → chunk-P7TPNRU4.js.map} +2 -2
- package/dist/esm/{chunk-F5ELD54X.js → chunk-QNOBB5HT.js} +2 -2
- package/dist/esm/{chunk-GV36OVX7.js → chunk-R67C5QTH.js} +2 -2
- package/dist/esm/{chunk-S4CU4XRB.js → chunk-VGFVSRWH.js} +2 -2
- package/dist/esm/chunk-VZ3IWSK6.js +158 -0
- package/dist/esm/chunk-VZ3IWSK6.js.map +7 -0
- package/dist/esm/{chunk-X4CMSAET.js → chunk-WSQWMVA2.js} +2 -2
- package/dist/esm/chunk-WYJP7HVL.js +26 -0
- package/dist/esm/chunk-WYJP7HVL.js.map +7 -0
- package/dist/esm/{chunk-OAG5T7NC.js → chunk-XEP6X7JU.js} +5 -5
- package/dist/esm/chunk-XEP6X7JU.js.map +7 -0
- package/dist/esm/components/AddressLookup/AddressLookup.js +6 -6
- package/dist/esm/components/AddressLookup/index.js +8 -8
- package/dist/esm/components/Breadcrumbs/Breadcrumbs.js +1 -1
- package/dist/esm/components/Breadcrumbs/index.js +3 -3
- package/dist/esm/components/Checkbox/index.js +1 -1
- package/dist/esm/components/Combobox/Combobox.js +5 -5
- package/dist/esm/components/Combobox/index.js +5 -5
- package/dist/esm/components/DateField/DateField.js +3 -3
- package/dist/esm/components/DateField/index.js +3 -3
- package/dist/esm/components/Drawer/index.js +3 -3
- package/dist/esm/components/DropdownMenu/Item.js +1 -1
- package/dist/esm/components/DropdownMenu/index.js +2 -2
- package/dist/esm/components/MaskedField/MaskedField.js +2 -2
- package/dist/esm/components/MaskedField/index.js +3 -3
- package/dist/esm/components/Modal/index.js +3 -3
- package/dist/esm/components/NumberField/NumberField.js +3 -3
- package/dist/esm/components/NumberField/index.js +3 -3
- package/dist/esm/components/PasswordField/PasswordField.js +3 -3
- package/dist/esm/components/PasswordField/index.js +3 -3
- package/dist/esm/components/Popover/Arrow.js +8 -0
- package/dist/esm/components/Popover/Arrow.js.map +7 -0
- package/dist/esm/components/Popover/Popover.js +5 -1
- package/dist/esm/components/Popover/index.js +5 -1
- package/dist/esm/components/Popover/useAutoUpdate.js +8 -0
- package/dist/esm/components/Popover/useAutoUpdate.js.map +7 -0
- package/dist/esm/components/Popover/useFloatingPosition.js +8 -0
- package/dist/esm/components/Popover/useFloatingPosition.js.map +7 -0
- package/dist/esm/components/Popover/useOutsidePress.js +8 -0
- package/dist/esm/components/Popover/useOutsidePress.js.map +7 -0
- package/dist/esm/components/TextField/TextField.js +2 -2
- package/dist/esm/components/TextField/adornmentWithClassName.js +1 -1
- package/dist/esm/components/TextField/index.js +2 -2
- package/dist/esm/components/index.js +81 -77
- package/dist/esm/index.js +81 -77
- package/dist/esm/meta.json +3495 -3149
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/components/Accordion/Accordion.d.ts +4 -4
- package/dist/types/components/Accordion/AccordionList.d.ts +4 -4
- package/dist/types/components/AddressLookup/AddressLookup.d.ts +4 -4
- package/dist/types/components/AddressLookup/LoqateAddressLookupService.d.ts +1 -1
- package/dist/types/components/Alert/Alert.d.ts +4 -4
- package/dist/types/components/Box/Box.d.ts +4 -4
- package/dist/types/components/Breadcrumbs/BreadcrumbItem.d.ts +4 -4
- package/dist/types/components/Breadcrumbs/Breadcrumbs.d.ts +4 -4
- package/dist/types/components/Button/Button.d.ts +4 -4
- package/dist/types/components/Checkbox/Checkbox.d.ts +4 -4
- package/dist/types/components/Checkbox/CheckboxGroup.d.ts +4 -4
- package/dist/types/components/Combobox/Combobox.d.ts +2 -5
- package/dist/types/components/Combobox/useComboboxOptions.d.ts +1 -1
- package/dist/types/components/Container/Container.d.ts +4 -4
- package/dist/types/components/DateField/DateField.d.ts +4 -4
- package/dist/types/components/Divider/Divider.d.ts +4 -4
- package/dist/types/components/Drawer/Content.d.ts +4 -4
- package/dist/types/components/Drawer/Drawer.d.ts +4 -4
- package/dist/types/components/Drawer/Header.d.ts +4 -4
- package/dist/types/components/DropdownMenu/DropdownMenu.d.ts +4 -4
- package/dist/types/components/DropdownMenu/Item.d.ts +4 -4
- package/dist/types/components/ErrorMessage/ErrorMessage.d.ts +4 -4
- package/dist/types/components/ExpandableText/ExpandableText.d.ts +4 -4
- package/dist/types/components/Fieldset/Fieldset.d.ts +4 -4
- package/dist/types/components/Flex/Flex.d.ts +4 -4
- package/dist/types/components/Grid/Grid.d.ts +4 -4
- package/dist/types/components/Grid/Item.d.ts +4 -4
- package/dist/types/components/Image/Image.d.ts +4 -4
- package/dist/types/components/Label/Label.d.ts +4 -4
- package/dist/types/components/Link/Link.d.ts +4 -4
- package/dist/types/components/List/List.d.ts +4 -4
- package/dist/types/components/List/ListItem.d.ts +4 -4
- package/dist/types/components/LoadingIndicator/LoadingIndicator.d.ts +4 -4
- package/dist/types/components/Logo/Logo.d.ts +4 -4
- package/dist/types/components/MaskedField/MaskedField.d.ts +4 -4
- package/dist/types/components/Modal/Content.d.ts +4 -4
- package/dist/types/components/Modal/Header.d.ts +4 -4
- package/dist/types/components/Modal/Modal.d.ts +4 -4
- package/dist/types/components/NumberField/NumberField.d.ts +4 -4
- package/dist/types/components/Option/Option.d.ts +4 -4
- package/dist/types/components/PasswordField/PasswordField.d.ts +4 -4
- package/dist/types/components/Popover/Arrow.d.ts +9 -0
- package/dist/types/components/Popover/useAutoUpdate.d.ts +9 -0
- package/dist/types/components/Popover/useFloatingPosition.d.ts +17 -0
- package/dist/types/components/Popover/useOutsidePress.d.ts +9 -0
- package/dist/types/components/Progress/Progress.d.ts +4 -4
- package/dist/types/components/Radio/Radio.d.ts +4 -4
- package/dist/types/components/Radio/RadioGroup.d.ts +4 -4
- package/dist/types/components/SVG/SVG.d.ts +4 -4
- package/dist/types/components/Segment/Segment.d.ts +4 -4
- package/dist/types/components/Segment/SegmentGroup.d.ts +4 -4
- package/dist/types/components/Select/Select.d.ts +4 -4
- package/dist/types/components/Stack/Stack.d.ts +4 -4
- package/dist/types/components/Switch/Switch.d.ts +4 -4
- package/dist/types/components/Table/Body.d.ts +4 -4
- package/dist/types/components/Table/Cell.d.ts +4 -4
- package/dist/types/components/Table/Foot.d.ts +4 -4
- package/dist/types/components/Table/Head.d.ts +4 -4
- package/dist/types/components/Table/HeaderCell.d.ts +4 -4
- package/dist/types/components/Table/Row.d.ts +4 -4
- package/dist/types/components/Table/Table.d.ts +4 -4
- package/dist/types/components/Text/Text.d.ts +4 -4
- package/dist/types/components/TextArea/TextArea.d.ts +4 -4
- package/dist/types/components/TextAreaInput/TextAreaInput.d.ts +4 -4
- package/dist/types/components/TextField/TextField.d.ts +1 -4
- package/dist/types/components/TextField/adornmentWithClassName.d.ts +3 -1
- package/dist/types/components/TextOrHTML/TextOrHTML.d.ts +4 -4
- package/dist/types/components/Title/Title.d.ts +4 -4
- package/dist/types/components/Toast/ToastOptionsDoc.d.ts +4 -8
- package/dist/types/components/Toast/Toaster.d.ts +4 -4
- package/dist/types/hooks/useButton/useButton.d.ts +5 -5
- package/dist/types/hooks/useLabel/useLabel.d.ts +1 -1
- package/package.json +11 -11
- package/src/components/Box/Box.test.tsx +1 -2
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +3 -7
- package/src/components/Button/Button.stories.tsx +1 -1
- package/src/components/Combobox/Combobox.tsx +2 -4
- package/src/components/DropdownMenu/DropdownMenu.stories.tsx +1 -1
- package/src/components/DropdownMenu/Item.tsx +3 -6
- package/src/components/Grid/Grid.stories.tsx +1 -1
- package/src/components/Popover/Arrow.tsx +25 -0
- package/src/components/Popover/Popover.characterization.test.tsx +269 -0
- package/src/components/Popover/Popover.stories.tsx +40 -3
- package/src/components/Popover/Popover.test.tsx +6 -2
- package/src/components/Popover/Popover.tsx +87 -81
- package/src/components/Popover/useAutoUpdate.ts +43 -0
- package/src/components/Popover/useFloatingPosition.ts +177 -0
- package/src/components/Popover/useOutsidePress.ts +31 -0
- package/src/components/TextField/TextField.tsx +3 -1
- package/src/components/TextField/adornmentWithClassName.ts +4 -3
- package/src/hooks/useBreakpoint/useBreakpoint.test.tsx +4 -4
- package/src/styles.d.ts +2 -0
- package/dist/esm/chunk-IQKS662C.js.map +0 -7
- package/dist/esm/chunk-O5YEU5TG.js +0 -155
- package/dist/esm/chunk-O5YEU5TG.js.map +0 -7
- package/dist/esm/chunk-OAG5T7NC.js.map +0 -7
- /package/dist/esm/{chunk-XNEQHHNV.js.map → chunk-5QMKPWB4.js.map} +0 -0
- /package/dist/esm/{chunk-PEEQNAIN.js.map → chunk-DMYDWKKA.js.map} +0 -0
- /package/dist/esm/{chunk-GJBH37DH.js.map → chunk-KFHPI67N.js.map} +0 -0
- /package/dist/esm/{chunk-OEDU5ZEA.js.map → chunk-KUH5AB5T.js.map} +0 -0
- /package/dist/esm/{chunk-F5ELD54X.js.map → chunk-QNOBB5HT.js.map} +0 -0
- /package/dist/esm/{chunk-GV36OVX7.js.map → chunk-R67C5QTH.js.map} +0 -0
- /package/dist/esm/{chunk-S4CU4XRB.js.map → chunk-VGFVSRWH.js.map} +0 -0
- /package/dist/esm/{chunk-X4CMSAET.js.map → chunk-WSQWMVA2.js.map} +0 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import type { CSSProperties, RefObject } from "react";
|
|
2
|
+
import { useCallback, useLayoutEffect } from "react";
|
|
3
|
+
|
|
4
|
+
type Placement = "bottom" | "top";
|
|
5
|
+
|
|
6
|
+
interface UseFloatingPositionArgs {
|
|
7
|
+
referenceRef: RefObject<HTMLElement | null>;
|
|
8
|
+
floatingRef: RefObject<HTMLDivElement | null>;
|
|
9
|
+
arrowRef: RefObject<SVGSVGElement | null>;
|
|
10
|
+
isOpen: boolean;
|
|
11
|
+
offsetPx: number;
|
|
12
|
+
arrowWidth: number;
|
|
13
|
+
useFixedStrategy: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface UseFloatingPositionResult {
|
|
17
|
+
initialFloatingStyles: CSSProperties;
|
|
18
|
+
initialArrowStyles: CSSProperties;
|
|
19
|
+
update: () => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Two positioning strategies:
|
|
23
|
+
// - `absolute` + document-relative coords (viewport rect + window.scrollY/X)
|
|
24
|
+
// when portalled to document.body. The initial containing block is the
|
|
25
|
+
// document, so absolute coords pin to the trigger and scroll natively.
|
|
26
|
+
// - `fixed` + viewport coords when portalled inside a <dialog> (top-layer).
|
|
27
|
+
// The dialog's own box would otherwise become the containing block for an
|
|
28
|
+
// `absolute` child, throwing off coordinates and triggering `overflow: hidden`
|
|
29
|
+
// clipping. `fixed` keeps the containing block as the viewport.
|
|
30
|
+
const ABSOLUTE_FLOATING_STYLES: CSSProperties = {
|
|
31
|
+
position: "absolute",
|
|
32
|
+
top: 0,
|
|
33
|
+
left: 0,
|
|
34
|
+
width: "max-content",
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const FIXED_FLOATING_STYLES: CSSProperties = {
|
|
38
|
+
position: "fixed",
|
|
39
|
+
top: 0,
|
|
40
|
+
left: 0,
|
|
41
|
+
width: "max-content",
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const INITIAL_ARROW_STYLES: CSSProperties = {
|
|
45
|
+
position: "absolute",
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const VIEWPORT_PADDING = 0;
|
|
49
|
+
|
|
50
|
+
// Properties that make an ancestor the containing block for a `position: fixed`
|
|
51
|
+
// descendant, overriding the initial viewport containing block. When the portal
|
|
52
|
+
// target (dialog) has any of these, `position: fixed` coords are interpreted
|
|
53
|
+
// relative to the dialog's box, not the viewport — we compensate by subtracting
|
|
54
|
+
// the dialog's viewport offset.
|
|
55
|
+
const createsFixedContainingBlock = (el: HTMLElement): boolean => {
|
|
56
|
+
const style = window.getComputedStyle(el);
|
|
57
|
+
return (
|
|
58
|
+
style.transform !== "none" ||
|
|
59
|
+
style.filter !== "none" ||
|
|
60
|
+
style.backdropFilter !== "none" ||
|
|
61
|
+
style.perspective !== "none" ||
|
|
62
|
+
/\b(transform|filter|perspective)\b/.test(style.willChange)
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const useFloatingPosition = ({
|
|
67
|
+
referenceRef,
|
|
68
|
+
floatingRef,
|
|
69
|
+
arrowRef,
|
|
70
|
+
isOpen,
|
|
71
|
+
offsetPx,
|
|
72
|
+
arrowWidth,
|
|
73
|
+
useFixedStrategy,
|
|
74
|
+
}: UseFloatingPositionArgs): UseFloatingPositionResult => {
|
|
75
|
+
// Writes styles directly to the DOM (bypassing React state) so scroll/resize
|
|
76
|
+
// handlers can update position in the same event-frame the browser uses to
|
|
77
|
+
// paint the scroll, eliminating the re-render lag that shows up as a
|
|
78
|
+
// trigger-vs-popover parallax on fast scroll.
|
|
79
|
+
const update = useCallback(() => {
|
|
80
|
+
const reference = referenceRef.current;
|
|
81
|
+
const floating = floatingRef.current;
|
|
82
|
+
if (!reference || !floating) return;
|
|
83
|
+
|
|
84
|
+
const refRect = reference.getBoundingClientRect();
|
|
85
|
+
const floatingWidth = floating.offsetWidth;
|
|
86
|
+
const floatingHeight = floating.offsetHeight;
|
|
87
|
+
const scrollX = useFixedStrategy ? 0 : window.scrollX;
|
|
88
|
+
const scrollY = useFixedStrategy ? 0 : window.scrollY;
|
|
89
|
+
|
|
90
|
+
// Clamp to the portal target's bounds when the dialog is a containing
|
|
91
|
+
// block (its own `overflow: hidden` would clip the popover). Otherwise
|
|
92
|
+
// clamp to the viewport.
|
|
93
|
+
const parent = floating.parentElement;
|
|
94
|
+
const parentIsCb =
|
|
95
|
+
useFixedStrategy && !!parent && createsFixedContainingBlock(parent);
|
|
96
|
+
const boundsRect = parentIsCb
|
|
97
|
+
? parent.getBoundingClientRect()
|
|
98
|
+
: {
|
|
99
|
+
left: 0,
|
|
100
|
+
top: 0,
|
|
101
|
+
right: window.innerWidth,
|
|
102
|
+
bottom: window.innerHeight,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const bottomTopViewport = refRect.bottom + offsetPx;
|
|
106
|
+
const topTopViewport = refRect.top - floatingHeight - offsetPx;
|
|
107
|
+
const overflowsBottom =
|
|
108
|
+
bottomTopViewport + floatingHeight > boundsRect.bottom;
|
|
109
|
+
const fitsTop = topTopViewport >= boundsRect.top;
|
|
110
|
+
const nextPlacement: Placement =
|
|
111
|
+
overflowsBottom && fitsTop ? "top" : "bottom";
|
|
112
|
+
|
|
113
|
+
const topViewport =
|
|
114
|
+
nextPlacement === "bottom" ? bottomTopViewport : topTopViewport;
|
|
115
|
+
|
|
116
|
+
const rawLeftViewport =
|
|
117
|
+
refRect.left + refRect.width / 2 - floatingWidth / 2;
|
|
118
|
+
const minLeftViewport = boundsRect.left + VIEWPORT_PADDING;
|
|
119
|
+
const maxLeftViewport = Math.max(
|
|
120
|
+
minLeftViewport,
|
|
121
|
+
boundsRect.right - floatingWidth - VIEWPORT_PADDING,
|
|
122
|
+
);
|
|
123
|
+
const leftViewport = Math.min(
|
|
124
|
+
Math.max(minLeftViewport, rawLeftViewport),
|
|
125
|
+
maxLeftViewport,
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// Subtract containing-block offset when the dialog is the CB, so
|
|
129
|
+
// `position: fixed` coords land at the intended viewport position.
|
|
130
|
+
const cbOffsetLeft = parentIsCb ? boundsRect.left : 0;
|
|
131
|
+
const cbOffsetTop = parentIsCb ? boundsRect.top : 0;
|
|
132
|
+
|
|
133
|
+
floating.style.top = `${topViewport + scrollY - cbOffsetTop}px`;
|
|
134
|
+
floating.style.left = `${leftViewport + scrollX - cbOffsetLeft}px`;
|
|
135
|
+
|
|
136
|
+
const arrow = arrowRef.current;
|
|
137
|
+
if (!arrow) return;
|
|
138
|
+
|
|
139
|
+
// Arrow coords are relative to the floating element, so scroll cancels out.
|
|
140
|
+
const arrowHalf = arrowWidth / 2;
|
|
141
|
+
const refCenterX = refRect.left + refRect.width / 2;
|
|
142
|
+
const rawArrowLeft = refCenterX - leftViewport - arrowHalf;
|
|
143
|
+
const maxArrowLeft = Math.max(0, floatingWidth - arrowWidth);
|
|
144
|
+
const arrowLeft = Math.min(Math.max(0, rawArrowLeft), maxArrowLeft);
|
|
145
|
+
|
|
146
|
+
arrow.style.left = `${arrowLeft}px`;
|
|
147
|
+
if (nextPlacement === "bottom") {
|
|
148
|
+
arrow.style.bottom = "100%";
|
|
149
|
+
arrow.style.top = "";
|
|
150
|
+
arrow.style.transform = "rotate(180deg)";
|
|
151
|
+
} else {
|
|
152
|
+
arrow.style.top = "100%";
|
|
153
|
+
arrow.style.bottom = "";
|
|
154
|
+
arrow.style.transform = "";
|
|
155
|
+
}
|
|
156
|
+
}, [
|
|
157
|
+
referenceRef,
|
|
158
|
+
floatingRef,
|
|
159
|
+
arrowRef,
|
|
160
|
+
offsetPx,
|
|
161
|
+
arrowWidth,
|
|
162
|
+
useFixedStrategy,
|
|
163
|
+
]);
|
|
164
|
+
|
|
165
|
+
useLayoutEffect(() => {
|
|
166
|
+
if (!isOpen) return;
|
|
167
|
+
update();
|
|
168
|
+
}, [isOpen, update]);
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
initialFloatingStyles: useFixedStrategy
|
|
172
|
+
? FIXED_FLOATING_STYLES
|
|
173
|
+
: ABSOLUTE_FLOATING_STYLES,
|
|
174
|
+
initialArrowStyles: INITIAL_ARROW_STYLES,
|
|
175
|
+
update,
|
|
176
|
+
};
|
|
177
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { RefObject } from "react";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
|
|
4
|
+
interface UseOutsidePressArgs {
|
|
5
|
+
referenceRef: RefObject<HTMLElement | null>;
|
|
6
|
+
floatingRef: RefObject<HTMLDivElement | null>;
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
onOutsidePress: (event: PointerEvent) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const useOutsidePress = ({
|
|
12
|
+
referenceRef,
|
|
13
|
+
floatingRef,
|
|
14
|
+
enabled,
|
|
15
|
+
onOutsidePress,
|
|
16
|
+
}: UseOutsidePressArgs): void => {
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!enabled) return;
|
|
19
|
+
|
|
20
|
+
const handler = (event: PointerEvent) => {
|
|
21
|
+
const target = event.target as Node | null;
|
|
22
|
+
if (!target) return;
|
|
23
|
+
if (referenceRef.current?.contains(target)) return;
|
|
24
|
+
if (floatingRef.current?.contains(target)) return;
|
|
25
|
+
onOutsidePress(event);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
document.addEventListener("pointerdown", handler);
|
|
29
|
+
return () => document.removeEventListener("pointerdown", handler);
|
|
30
|
+
}, [enabled, onOutsidePress, referenceRef, floatingRef]);
|
|
31
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import classNames from "classnames/dedupe";
|
|
4
|
+
import { memo } from "react";
|
|
4
5
|
import type {
|
|
5
6
|
HTMLInputTypeAttribute,
|
|
6
7
|
ReactElement,
|
|
@@ -52,7 +53,7 @@ export interface TextFieldProps
|
|
|
52
53
|
|
|
53
54
|
export type TextFieldRef = Ref<TextFieldElementType>;
|
|
54
55
|
|
|
55
|
-
const
|
|
56
|
+
const TextFieldInner = ({ ref, ...props }: TextFieldProps) => {
|
|
56
57
|
const {
|
|
57
58
|
isDisabled,
|
|
58
59
|
type = "text",
|
|
@@ -166,5 +167,6 @@ const TextField = ({ ref, ...props }: TextFieldProps) => {
|
|
|
166
167
|
);
|
|
167
168
|
};
|
|
168
169
|
|
|
170
|
+
const TextField = memo(TextFieldInner);
|
|
169
171
|
TextField.displayName = "TextField";
|
|
170
172
|
export { TextField };
|
|
@@ -9,11 +9,12 @@ export const adornmentWithClassName = (
|
|
|
9
9
|
) => {
|
|
10
10
|
if (!component) return null;
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
const typedComponent = component as ReactElement<{ className?: string }>;
|
|
13
|
+
return cloneElement(typedComponent, {
|
|
13
14
|
className: classNames(
|
|
14
|
-
|
|
15
|
+
typedComponent.props.className,
|
|
15
16
|
validationClasses,
|
|
16
17
|
className,
|
|
17
18
|
),
|
|
18
|
-
}
|
|
19
|
+
});
|
|
19
20
|
};
|
|
@@ -139,7 +139,7 @@ describe("useBreakpoint", () => {
|
|
|
139
139
|
it.each([...expected])(
|
|
140
140
|
"it returns %s for breakpoint %s",
|
|
141
141
|
(expectedResult, breakpoint) => {
|
|
142
|
-
setWindowWidth(value
|
|
142
|
+
setWindowWidth(value);
|
|
143
143
|
|
|
144
144
|
const { result } = renderHook(() => useBreakpoint());
|
|
145
145
|
expect(result.current.up(breakpoint)).toBe(expectedResult);
|
|
@@ -222,7 +222,7 @@ describe("useBreakpoint", () => {
|
|
|
222
222
|
it.each([...expected])(
|
|
223
223
|
"it returns %s for breakpoint %s",
|
|
224
224
|
(expectedResult, breakpoint) => {
|
|
225
|
-
setWindowWidth(value
|
|
225
|
+
setWindowWidth(value);
|
|
226
226
|
|
|
227
227
|
const { result } = renderHook(() => useBreakpoint());
|
|
228
228
|
expect(result.current.down(breakpoint)).toBe(expectedResult);
|
|
@@ -340,7 +340,7 @@ describe("useBreakpoint", () => {
|
|
|
340
340
|
it.each([...expected])(
|
|
341
341
|
"it returns %s for breakpoint %s",
|
|
342
342
|
(expectedResult, breakpoint) => {
|
|
343
|
-
setWindowWidth(value
|
|
343
|
+
setWindowWidth(value);
|
|
344
344
|
|
|
345
345
|
const { result } = renderHook(() =>
|
|
346
346
|
useBreakpoint(customBreakpoints),
|
|
@@ -419,7 +419,7 @@ describe("useBreakpoint", () => {
|
|
|
419
419
|
it.each([...expected])(
|
|
420
420
|
"it returns %s for breakpoint %s",
|
|
421
421
|
(expectedResult, breakpoint) => {
|
|
422
|
-
setWindowWidth(value
|
|
422
|
+
setWindowWidth(value);
|
|
423
423
|
|
|
424
424
|
const { result } = renderHook(() => useBreakpoint());
|
|
425
425
|
expect(result.current.down(breakpoint)).toBe(expectedResult);
|
package/src/styles.d.ts
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/components/TextField/TextField.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\";\n\nimport classNames from \"classnames/dedupe\";\nimport type {\n HTMLInputTypeAttribute,\n ReactElement,\n ReactNode,\n Ref,\n RefAttributes,\n} from \"react\";\nimport type { UseTextFieldProps } from \"../../hooks\";\nimport { useTextField, useValidationClasses } from \"../../hooks\";\nimport type { DOMProps, FocusEvents } from \"../../types\";\nimport { ErrorMessage } from \"../ErrorMessage\";\nimport { Label } from \"../Label\";\nimport { Stack } from \"../Stack\";\nimport { adornmentWithClassName } from \"./adornmentWithClassName\";\nimport \"./TextField.css\";\n\nexport type TextFieldElementType = HTMLInputElement;\nexport interface TextFieldProps\n extends\n DOMProps,\n FocusEvents,\n UseTextFieldProps,\n RefAttributes<TextFieldElementType> {\n className?: string;\n errorMessage?: string;\n children?: ReactNode;\n label?: string;\n type?: Exclude<\n HTMLInputTypeAttribute,\n | \"button\"\n | \"checkbox\"\n | \"color\"\n | \"date\"\n | \"datetime-local\"\n | \"file\"\n | \"image\"\n | \"month\"\n | \"radio\"\n | \"range\"\n | \"reset\"\n | \"submit\"\n | \"week\"\n >;\n prefixInside?: ReactElement;\n prefixOutside?: ReactElement;\n suffixInside?: ReactElement;\n suffixOutside?: ReactElement;\n}\n\nexport type TextFieldRef = Ref<TextFieldElementType>;\n\nconst TextField = ({ ref, ...props }: TextFieldProps) => {\n const {\n isDisabled,\n type = \"text\",\n isInvalid,\n className,\n label,\n errorMessage,\n children,\n isRequired,\n prefixInside,\n prefixOutside,\n suffixInside,\n suffixOutside,\n autoComplete,\n isReadOnly,\n ...otherProps\n } = props;\n\n const resolvedAutoComplete =\n autoComplete ??\n (type === \"email\" ? \"email\" : type === \"tel\" ? \"tel\" : undefined);\n\n const { inputProps, labelProps, errorMessageProps } = useTextField({\n ...props,\n autoComplete: resolvedAutoComplete,\n \"aria-errormessage\": errorMessage,\n });\n\n const hidden = type === \"hidden\";\n\n const validationClasses = useValidationClasses({ isInvalid });\n\n const textfieldClasses = {\n \"--is-disabled\": isDisabled,\n \"--is-required\": typeof isRequired === \"boolean\" && isRequired,\n \"--is-optional\": typeof isRequired === \"boolean\" && !isRequired,\n \"--is-hidden\": hidden,\n [className || \"\"]: true,\n };\n\n const sharedClasses = classNames(validationClasses, textfieldClasses);\n\n const labelClasses = classNames(\n {\n \"--is-disabled\": isDisabled,\n },\n validationClasses,\n );\n\n const containerClasses = classNames(\n \"mobius\",\n \"mobius-text-field\",\n sharedClasses,\n );\n\n const inputClasses = classNames(\n \"mobius\",\n \"mobius-text-field__input\",\n sharedClasses,\n );\n\n const inputWrapperClasses = classNames(\n \"mobius-text-field__input-wrapper\",\n sharedClasses,\n );\n\n return (\n <Stack gap=\"xs\" className={containerClasses}>\n {label && !hidden && (\n <Label {...labelProps} className={labelClasses}>\n {label}\n </Label>\n )}\n <div className=\"mobius-text-field__inner-container\">\n {adornmentWithClassName(\n prefixOutside,\n labelClasses,\n \"mobius-text-field__prefix-outside\",\n )}\n <div className={inputWrapperClasses}>\n {adornmentWithClassName(\n prefixInside,\n labelClasses,\n \"mobius-text-field__prefix-inside\",\n )}\n <input\n {...otherProps}\n {...inputProps}\n ref={ref}\n type={type}\n className={inputClasses}\n />\n {adornmentWithClassName(\n suffixInside,\n labelClasses,\n \"mobius-text-field__suffix-inside\",\n )}\n </div>\n {adornmentWithClassName(\n suffixOutside,\n labelClasses,\n \"mobius-text-field__suffix-outside\",\n )}\n </div>\n {children && (\n <div className=\"mobius-text-field__children\">{children}</div>\n )}\n\n <ErrorMessage {...errorMessageProps} errorMessage={errorMessage} />\n </Stack>\n );\n};\n\nTextField.displayName = \"TextField\";\nexport { TextField };\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAEA,OAAO,gBAAgB;AAevB,OAAO;AA2GC,cAUA,YAVA;AAtER,IAAM,YAAY,CAAC,EAAE,KAAK,GAAG,MAAM,MAAsB;AACvD,QAAM;AAAA,IACJ;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,uBACJ,iBACC,SAAS,UAAU,UAAU,SAAS,QAAQ,QAAQ;AAEzD,QAAM,EAAE,YAAY,YAAY,kBAAkB,IAAI,aAAa;AAAA,IACjE,GAAG;AAAA,IACH,cAAc;AAAA,IACd,qBAAqB;AAAA,EACvB,CAAC;AAED,QAAM,SAAS,SAAS;AAExB,QAAM,oBAAoB,qBAAqB,EAAE,UAAU,CAAC;AAE5D,QAAM,mBAAmB;AAAA,IACvB,iBAAiB;AAAA,IACjB,iBAAiB,OAAO,eAAe,aAAa;AAAA,IACpD,iBAAiB,OAAO,eAAe,aAAa,CAAC;AAAA,IACrD,eAAe;AAAA,IACf,CAAC,aAAa,EAAE,GAAG;AAAA,EACrB;AAEA,QAAM,gBAAgB,WAAW,mBAAmB,gBAAgB;AAEpE,QAAM,eAAe;AAAA,IACnB;AAAA,MACE,iBAAiB;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AAEA,QAAM,mBAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,eAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,sBAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,EACF;AAEA,SACE,qBAAC,SAAM,KAAI,MAAK,WAAW,kBACxB;AAAA,aAAS,CAAC,UACT,oBAAC,SAAO,GAAG,YAAY,WAAW,cAC/B,iBACH;AAAA,IAEF,qBAAC,SAAI,WAAU,sCACZ;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,qBAAC,SAAI,WAAW,qBACb;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACE,GAAG;AAAA,YACH,GAAG;AAAA,YACJ;AAAA,YACA;AAAA,YACA,WAAW;AAAA;AAAA,QACb;AAAA,QACC;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,SACF;AAAA,MACC;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,OACF;AAAA,IACC,YACC,oBAAC,SAAI,WAAU,+BAA+B,UAAS;AAAA,IAGzD,oBAAC,gBAAc,GAAG,mBAAmB,cAA4B;AAAA,KACnE;AAEJ;AAEA,UAAU,cAAc;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Button
|
|
3
|
-
} from "./chunk-FD3JTY5L.js";
|
|
4
|
-
import {
|
|
5
|
-
Icon
|
|
6
|
-
} from "./chunk-TKIP5Q5H.js";
|
|
7
|
-
|
|
8
|
-
// src/components/Popover/Popover.tsx
|
|
9
|
-
import {
|
|
10
|
-
FloatingArrow,
|
|
11
|
-
arrow,
|
|
12
|
-
autoUpdate,
|
|
13
|
-
flip,
|
|
14
|
-
offset,
|
|
15
|
-
shift,
|
|
16
|
-
useDismiss,
|
|
17
|
-
useFloating,
|
|
18
|
-
useInteractions
|
|
19
|
-
} from "@floating-ui/react";
|
|
20
|
-
import { cross } from "@simplybusiness/icons";
|
|
21
|
-
import classNames from "classnames/dedupe";
|
|
22
|
-
import { cloneElement, useCallback, useEffect, useRef, useState } from "react";
|
|
23
|
-
import { useWindowEvent } from "@simplybusiness/mobius-hooks";
|
|
24
|
-
import "@simplybusiness/mobius/src/components/Popover/Popover.css";
|
|
25
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
26
|
-
var OFFSET_FROM_CONTENT_DEFAULT = 10;
|
|
27
|
-
var Popover = (props) => {
|
|
28
|
-
const { trigger, children, onOpen, onClose, className } = props;
|
|
29
|
-
const arrowRef = useRef(null);
|
|
30
|
-
const floatingContainerRef = useRef(null);
|
|
31
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
32
|
-
const { refs, floatingStyles, context } = useFloating({
|
|
33
|
-
open: isOpen,
|
|
34
|
-
onOpenChange: setIsOpen,
|
|
35
|
-
whileElementsMounted: autoUpdate,
|
|
36
|
-
middleware: [
|
|
37
|
-
arrow({
|
|
38
|
-
element: arrowRef
|
|
39
|
-
}),
|
|
40
|
-
offset(OFFSET_FROM_CONTENT_DEFAULT),
|
|
41
|
-
shift(),
|
|
42
|
-
flip()
|
|
43
|
-
]
|
|
44
|
-
});
|
|
45
|
-
const dismiss = useDismiss(context, {
|
|
46
|
-
bubbles: true,
|
|
47
|
-
outsidePress: (event) => {
|
|
48
|
-
const toggle = refs.reference.current;
|
|
49
|
-
const isToggleClick = !toggle?.contains(event.target);
|
|
50
|
-
if (isToggleClick) {
|
|
51
|
-
onClose?.();
|
|
52
|
-
}
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
const { getReferenceProps, getFloatingProps } = useInteractions([dismiss]);
|
|
57
|
-
const containerClasses = classNames(
|
|
58
|
-
"mobius",
|
|
59
|
-
"mobius-popover__container",
|
|
60
|
-
className
|
|
61
|
-
);
|
|
62
|
-
const setFloatingRef = useCallback(
|
|
63
|
-
(node) => {
|
|
64
|
-
refs.setFloating(node);
|
|
65
|
-
floatingContainerRef.current = node;
|
|
66
|
-
},
|
|
67
|
-
[refs]
|
|
68
|
-
);
|
|
69
|
-
useEffect(() => {
|
|
70
|
-
const el = floatingContainerRef.current;
|
|
71
|
-
if (!el) return;
|
|
72
|
-
const preventLabelActivation = (e) => {
|
|
73
|
-
const target = e.target;
|
|
74
|
-
if (!target.closest("a[href], input, select, textarea")) {
|
|
75
|
-
e.preventDefault();
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
el.addEventListener("click", preventLabelActivation);
|
|
79
|
-
return () => el.removeEventListener("click", preventLabelActivation);
|
|
80
|
-
}, [isOpen]);
|
|
81
|
-
const toggleVisibility = () => {
|
|
82
|
-
if (isOpen) {
|
|
83
|
-
setIsOpen(false);
|
|
84
|
-
onClose?.();
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
setIsOpen(true);
|
|
88
|
-
onOpen?.();
|
|
89
|
-
};
|
|
90
|
-
const triggerComponent = cloneElement(trigger, {
|
|
91
|
-
ref: refs.setReference,
|
|
92
|
-
className: classNames(
|
|
93
|
-
trigger.props.className,
|
|
94
|
-
"mobius-popover__toggle"
|
|
95
|
-
),
|
|
96
|
-
onClick: toggleVisibility,
|
|
97
|
-
...getReferenceProps()
|
|
98
|
-
});
|
|
99
|
-
useWindowEvent("keydown", (e) => {
|
|
100
|
-
if (e.key === "Escape") {
|
|
101
|
-
onClose?.();
|
|
102
|
-
e.preventDefault();
|
|
103
|
-
e.stopPropagation();
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
107
|
-
triggerComponent,
|
|
108
|
-
isOpen && /* @__PURE__ */ jsxs(
|
|
109
|
-
"div",
|
|
110
|
-
{
|
|
111
|
-
className: containerClasses,
|
|
112
|
-
ref: setFloatingRef,
|
|
113
|
-
style: floatingStyles,
|
|
114
|
-
...getFloatingProps(),
|
|
115
|
-
children: [
|
|
116
|
-
/* @__PURE__ */ jsxs("div", { className: "mobius-popover", children: [
|
|
117
|
-
/* @__PURE__ */ jsx("header", { className: "mobius-popover__header", children: /* @__PURE__ */ jsx(
|
|
118
|
-
Button,
|
|
119
|
-
{
|
|
120
|
-
type: "button",
|
|
121
|
-
className: "mobius-popover__close-button",
|
|
122
|
-
onClick: toggleVisibility,
|
|
123
|
-
"aria-label": "Close",
|
|
124
|
-
variant: "ghost",
|
|
125
|
-
children: /* @__PURE__ */ jsx(
|
|
126
|
-
Icon,
|
|
127
|
-
{
|
|
128
|
-
icon: cross,
|
|
129
|
-
size: "md",
|
|
130
|
-
className: "mobius-popover__close-icon"
|
|
131
|
-
}
|
|
132
|
-
)
|
|
133
|
-
}
|
|
134
|
-
) }),
|
|
135
|
-
/* @__PURE__ */ jsx("div", { className: "mobius-popover__body", children })
|
|
136
|
-
] }),
|
|
137
|
-
/* @__PURE__ */ jsx(
|
|
138
|
-
FloatingArrow,
|
|
139
|
-
{
|
|
140
|
-
ref: arrowRef,
|
|
141
|
-
context,
|
|
142
|
-
width: 20,
|
|
143
|
-
className: "mobius-popover__arrow-icon"
|
|
144
|
-
}
|
|
145
|
-
)
|
|
146
|
-
]
|
|
147
|
-
}
|
|
148
|
-
)
|
|
149
|
-
] });
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
export {
|
|
153
|
-
Popover
|
|
154
|
-
};
|
|
155
|
-
//# sourceMappingURL=chunk-O5YEU5TG.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/components/Popover/Popover.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n FloatingArrow,\n arrow,\n autoUpdate,\n flip,\n offset,\n shift,\n useDismiss,\n useFloating,\n useInteractions,\n} from \"@floating-ui/react\";\nimport { cross } from \"@simplybusiness/icons\";\nimport classNames from \"classnames/dedupe\";\nimport type { ReactElement, ReactNode, RefAttributes } from \"react\";\nimport { cloneElement, useCallback, useEffect, useRef, useState } from \"react\";\nimport { useWindowEvent } from \"@simplybusiness/mobius-hooks\";\nimport type { DOMProps } from \"../../types\";\nimport { Button } from \"../Button\";\nimport { Icon } from \"../Icon\";\nimport \"./Popover.css\";\n\nexport type PopoverElementType = HTMLDivElement;\n\nexport interface PopoverProps\n extends DOMProps, RefAttributes<PopoverElementType> {\n children?: ReactNode;\n trigger: ReactElement;\n /** Callback that fires each time the accordion is opened */\n onOpen?: () => void;\n /** Callback that fires each time the accordion is closed */\n onClose?: () => void;\n /** Custom class name for setting specific CSS */\n className?: string;\n}\n\nconst OFFSET_FROM_CONTENT_DEFAULT = 10;\n\nexport const Popover = (props: PopoverProps) => {\n const { trigger, children, onOpen, onClose, className } = props;\n const arrowRef = useRef(null);\n const floatingContainerRef = useRef<HTMLDivElement | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const { refs, floatingStyles, context } = useFloating({\n open: isOpen,\n onOpenChange: setIsOpen,\n whileElementsMounted: autoUpdate,\n middleware: [\n arrow({\n element: arrowRef,\n }),\n offset(OFFSET_FROM_CONTENT_DEFAULT),\n shift(),\n flip(),\n ],\n });\n const dismiss = useDismiss(context, {\n bubbles: true,\n outsidePress: (event: MouseEvent) => {\n // Prevent 'onClose' from firing when clicking the toggle to close\n const toggle = refs.reference.current as HTMLElement;\n const isToggleClick = !toggle?.contains(event.target as HTMLElement);\n if (isToggleClick) {\n onClose?.();\n }\n return true;\n },\n });\n const { getReferenceProps, getFloatingProps } = useInteractions([dismiss]);\n\n const containerClasses = classNames(\n \"mobius\",\n \"mobius-popover__container\",\n className,\n );\n\n const setFloatingRef = useCallback(\n (node: HTMLDivElement | null) => {\n refs.setFloating(node);\n floatingContainerRef.current = node;\n },\n [refs],\n );\n\n // Native listener to prevent clicks inside the popover from activating\n // interactive ancestors. Must be native because React's onClick fires\n // too late via delegation.\n useEffect(() => {\n const el = floatingContainerRef.current;\n if (!el) return;\n\n const preventLabelActivation = (e: Event) => {\n const target = e.target as HTMLElement;\n // Allow default behavior for interactive elements (links, inputs, etc.)\n // so they remain functional inside the popover.\n if (!target.closest(\"a[href], input, select, textarea\")) {\n e.preventDefault();\n }\n };\n el.addEventListener(\"click\", preventLabelActivation);\n return () => el.removeEventListener(\"click\", preventLabelActivation);\n }, [isOpen]);\n\n const toggleVisibility = () => {\n if (isOpen) {\n setIsOpen(false);\n onClose?.();\n return;\n }\n\n setIsOpen(true);\n onOpen?.();\n };\n\n const triggerComponent = cloneElement(trigger, {\n ref: refs.setReference,\n className: classNames(\n (trigger.props as { className?: string }).className,\n \"mobius-popover__toggle\",\n ),\n onClick: toggleVisibility,\n ...getReferenceProps(),\n } as Record<string, unknown>);\n\n useWindowEvent(\"keydown\", e => {\n if (e.key === \"Escape\") {\n onClose?.();\n e.preventDefault();\n e.stopPropagation();\n }\n });\n\n return (\n <>\n {triggerComponent}\n {isOpen && (\n <div\n className={containerClasses}\n ref={setFloatingRef}\n style={floatingStyles}\n {...getFloatingProps()}\n >\n <div className=\"mobius-popover\">\n <header className=\"mobius-popover__header\">\n <Button\n type=\"button\"\n className=\"mobius-popover__close-button\"\n onClick={toggleVisibility}\n aria-label=\"Close\"\n variant=\"ghost\"\n >\n <Icon\n icon={cross}\n size=\"md\"\n className=\"mobius-popover__close-icon\"\n />\n </Button>\n </header>\n <div className=\"mobius-popover__body\">{children}</div>\n </div>\n <FloatingArrow\n ref={arrowRef}\n context={context}\n width={20}\n className=\"mobius-popover__arrow-icon\"\n />\n </div>\n )}\n </>\n );\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/components/Combobox/Combobox.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useOnUnmount } from \"@simplybusiness/mobius-hooks\";\nimport classNames from \"classnames/dedupe\";\nimport type React from \"react\";\nimport type { FocusEvent } from \"react\";\nimport { useEffect, useId, useRef, useState } from \"react\";\nimport { useBreakpoint } from \"../../hooks\";\nimport { TextField } from \"../TextField\";\nimport { VisuallyHidden } from \"../VisuallyHidden\";\nimport { Listbox } from \"./Listbox\"; // Import Listbox component\nimport type { ComboboxOption, ComboboxProps, ComboboxRef } from \"./types\";\nimport { useComboboxHighlight } from \"./useComboboxHighlight\";\nimport { useComboboxOptions } from \"./useComboboxOptions\";\nimport { getOptionLabel, getOptionValue, isOptionGroup } from \"./utils\";\nimport \"./Combobox.css\";\n\nconst ComboboxInner = <T extends ComboboxOption>({\n ref,\n ...props\n}: ComboboxProps<T>) => {\n const {\n id,\n defaultValue,\n value,\n options,\n asyncOptions,\n delay,\n minSearchLength,\n onSelected,\n className,\n placeholder,\n icon,\n onBlur,\n onFocus,\n onChange,\n // onSearched, // unused prop, consider removing\n optionComponent,\n optionTestIdPrefix,\n errorMessage,\n ...otherProps\n } = props;\n // Avoid re-fetching after selecting an option\n const skipNextDebounceRef = useRef(false);\n const fallbackRef = useRef<HTMLInputElement>(null);\n const [inputValue, setInputValue] = useState(defaultValue || \"\");\n const [isOpen, setIsOpen] = useState(false);\n const [isChanging, setIsChanging] = useState(false);\n const { filteredOptions, updateFilteredOptions, isLoading, error } =\n useComboboxOptions({\n options,\n asyncOptions,\n inputValue,\n delay,\n minSearchLength,\n skipNextDebounceRef,\n });\n const [validationError, setValidationError] = useState(\n error?.message || errorMessage,\n );\n const {\n highlightedIndex,\n highlightedGroupIndex,\n highlightNextOption,\n highlightPreviousOption,\n highlightFirstOption,\n highlightLastOption,\n clearHighlight,\n } = useComboboxHighlight(filteredOptions);\n\n const inputRef = ref || fallbackRef;\n const listboxId = useId();\n const statusId = useId();\n const blurTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const userInteractedRef = useRef(false);\n const justSelectedRef = useRef(false);\n const { down } = useBreakpoint();\n const isMobile = down(\"md\");\n\n useEffect(() => {\n setValidationError(error?.message || errorMessage);\n }, [error, errorMessage]);\n\n // Helper to create properly-typed empty value based on option type\n const getEmptyValue = (): T => {\n // Check first available option to determine if we're using string or object options\n const firstOption = filteredOptions\n ? isOptionGroup(filteredOptions)\n ? filteredOptions[0]?.options[0]\n : filteredOptions[0]\n : options\n ? isOptionGroup(options)\n ? options[0]?.options[0]\n : options[0]\n : undefined;\n\n // If options are strings, return empty string\n if (typeof firstOption === \"string\") {\n return \"\" as T;\n }\n\n // If options are objects, return empty object with same shape\n return { label: \"\", value: \"\" } as T;\n };\n\n const handleFocus = (e: FocusEvent) => {\n onFocus?.(e);\n if (!filteredOptions || filteredOptions.length === 0) return;\n if (blurTimeoutRef.current) {\n clearTimeout(blurTimeoutRef.current);\n blurTimeoutRef.current = null;\n }\n\n // Check if this is natural focus (user click/Tab) or programmatic focus\n const isNaturalFocus =\n userInteractedRef.current || e.relatedTarget !== null;\n if (userInteractedRef.current) {\n userInteractedRef.current = false;\n }\n\n // Block opening only if programmatic focus right after selection\n if (justSelectedRef.current && !isNaturalFocus) {\n return;\n }\n\n // Open dropdown for natural focus\n if (isNaturalFocus) {\n setIsOpen(true);\n justSelectedRef.current = false;\n }\n };\n\n useEffect(() => {\n if (!inputRef || typeof inputRef === \"function\") return;\n const inputElement = inputRef.current;\n if (!inputElement) return;\n\n const handleMouseDown = () => {\n // Track that user clicked/interacted with input\n userInteractedRef.current = true;\n };\n\n inputElement.addEventListener(\"mousedown\", handleMouseDown);\n return () => {\n inputElement.removeEventListener(\"mousedown\", handleMouseDown);\n };\n }, [inputRef]);\n\n useOnUnmount(() => {\n if (blurTimeoutRef.current) {\n clearTimeout(blurTimeoutRef.current);\n }\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n setInputValue(newValue);\n setValidationError(undefined);\n justSelectedRef.current = false;\n setIsChanging(true);\n // Only open immediately for sync options; async options controlled by useEffect\n if (!asyncOptions) {\n setIsOpen(true);\n }\n clearHighlight();\n onChange?.(e);\n };\n\n const handleOptionSelect = (option: T) => {\n const val = getOptionValue(option);\n\n // Allow empty values to pass through\n if (!val && val !== \"\") return;\n\n if (\n typeof option === \"object\" &&\n \"callback\" in option &&\n option.callback &&\n typeof option.callback === \"function\"\n ) {\n justSelectedRef.current = true;\n setTimeout(() => {\n if (inputRef && typeof inputRef !== \"function\" && inputRef.current) {\n inputRef.current.focus();\n }\n }, 0);\n const callbackPromise = option.callback();\n updateFilteredOptions(callbackPromise);\n callbackPromise\n .then(() => {\n setIsOpen(true);\n setIsChanging(true);\n })\n .catch(() => {\n // error handled inside updateFilteredOptions via setError\n });\n return;\n }\n\n // Prevent re-fetching options after selecting an option\n skipNextDebounceRef.current = true;\n justSelectedRef.current = true;\n\n setIsChanging(false);\n setValidationError(undefined);\n setIsOpen(false);\n setInputValue(val);\n onSelected?.(option);\n };\n\n const getFirstOption = () => {\n if (!filteredOptions) return undefined;\n if (isOptionGroup(filteredOptions)) {\n return filteredOptions[0]?.options[0];\n }\n\n return filteredOptions[0];\n };\n\n const getHighlightedOption = () => {\n if (!filteredOptions) return undefined;\n if (highlightedIndex === -1) return undefined;\n\n if (isOptionGroup(filteredOptions)) {\n const group = filteredOptions[highlightedGroupIndex];\n return group?.options[highlightedIndex];\n }\n\n return filteredOptions[highlightedIndex];\n };\n\n const getHighlightedOptionId = () => {\n const option = getHighlightedOption();\n if (!option) return undefined;\n\n if (isOptionGroup(filteredOptions)) {\n return `${listboxId}-option-${highlightedGroupIndex}-${highlightedIndex}`;\n }\n\n return `${listboxId}-option-${highlightedIndex}`;\n };\n\n const handleBlur = (e: FocusEvent<Element, Element>) => {\n // Force selection if user has matched an entry by typing (not already selected)\n // Defer this to allow natural focus flow to complete first\n if (!justSelectedRef.current) {\n const typedText = inputValue.trim();\n const typedTextLower = typedText.toLowerCase();\n const highlightedOption = getHighlightedOption();\n const label = getOptionLabel(highlightedOption);\n\n if (typedTextLower === label?.toLowerCase()) {\n // Exact match with an option\n setTimeout(() => {\n handleOptionSelect(highlightedOption as T);\n }, 0);\n } else if (typedText === \"\") {\n // Allow empty values\n setTimeout(() => {\n handleOptionSelect(getEmptyValue());\n }, 0);\n } else {\n // Invalid value (not in options and not empty)\n setValidationError(\n errorMessage || \"Please select an option from the list\",\n );\n setTimeout(() => {\n setInputValue(\"\");\n }, 0);\n }\n }\n\n blurTimeoutRef.current = setTimeout(() => {\n onBlur?.(e);\n setIsOpen(false);\n setIsChanging(false);\n }, 150);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n justSelectedRef.current = false;\n setIsOpen(true);\n highlightNextOption();\n break;\n case \"ArrowUp\":\n e.preventDefault();\n justSelectedRef.current = false;\n setIsOpen(true);\n highlightPreviousOption();\n break;\n case \"Home\":\n e.preventDefault();\n justSelectedRef.current = false;\n setIsOpen(true);\n highlightFirstOption();\n break;\n case \"End\":\n e.preventDefault();\n justSelectedRef.current = false;\n setIsOpen(true);\n highlightLastOption();\n break;\n case \"Enter\":\n e.preventDefault();\n if (isOpen) {\n const selectedOption = getHighlightedOption() || getFirstOption();\n if (selectedOption) {\n handleOptionSelect(selectedOption);\n }\n }\n break;\n case \"Escape\":\n e.preventDefault();\n setInputValue(\"\");\n setIsOpen(false);\n clearHighlight();\n break;\n default:\n // Do nothing\n }\n };\n\n useEffect(() => {\n if (value) {\n setInputValue(value);\n }\n }, [value]);\n\n // Open and close the combobox based on async filtered options\n useEffect(() => {\n if (asyncOptions && isChanging) {\n setIsOpen(!!filteredOptions && filteredOptions.length > 0);\n }\n }, [filteredOptions, asyncOptions, isChanging]);\n\n const classes = classNames(\n \"mobius mobius-combobox\",\n {\n \"mobius-combobox--is-expanded\": isOpen,\n \"mobius-combobox--is-loading\": isLoading,\n \"mobius-combobox--is-mobile\": isMobile,\n },\n className,\n );\n\n const getStatusMessage = () => {\n if (isLoading) return \"Loading options\";\n if (!filteredOptions || filteredOptions.length === 0) {\n return isChanging ? \"No options found\" : \"\";\n }\n const count = isOptionGroup(filteredOptions)\n ? filteredOptions.reduce((sum, group) => sum + group.options.length, 0)\n : filteredOptions.length;\n return isOpen && isChanging\n ? `${count} option${count === 1 ? \"\" : \"s\"} available`\n : \"\";\n };\n\n return (\n <div id={id} data-testid=\"mobius-combobox__wrapper\" className={classes}>\n <VisuallyHidden\n role=\"status\"\n aria-live=\"polite\"\n id={statusId}\n elementType=\"div\"\n className=\"mobius-combobox__status\"\n >\n {getStatusMessage()}\n </VisuallyHidden>\n <TextField\n {...otherProps}\n className=\"mobius-combobox__input\"\n role=\"combobox\"\n value={inputValue}\n placeholder={placeholder}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n onChange={handleInputChange}\n autoComplete=\"off\"\n aria-describedby={isLoading ? statusId : undefined}\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n aria-controls={isOpen ? listboxId : undefined}\n aria-expanded={isOpen}\n aria-activedescendant={\n highlightedIndex === -1 ? undefined : getHighlightedOptionId()\n }\n prefixInside={icon}\n ref={inputRef}\n errorMessage={errorMessage || validationError || error?.message}\n />\n <Listbox\n id={listboxId}\n isOpen={isOpen}\n isLoading={isLoading}\n options={filteredOptions}\n highlightedIndex={highlightedIndex}\n highlightedGroupIndex={highlightedGroupIndex}\n onOptionSelect={handleOptionSelect}\n optionComponent={optionComponent}\n optionTestIdPrefix={optionTestIdPrefix}\n />\n </div>\n );\n};\n\nexport const Combobox = ComboboxInner as <T extends ComboboxOption>(\n props: ComboboxProps<T> & { ref?: ComboboxRef },\n) => React.JSX.Element;\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|