@jobber/components 8.14.0 → 8.15.0
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/FilterPicker.d.ts +1 -0
- package/{Combobox.js → FilterPicker.js} +3 -3
- package/dist/Autocomplete-es.js +1 -1
- package/dist/BottomSheet-cjs.js +109 -77
- package/dist/BottomSheet-es.js +103 -75
- package/dist/Card/index.cjs +1 -2
- package/dist/Card/index.mjs +1 -2
- package/dist/DataDump/index.cjs +1 -2
- package/dist/DataDump/index.mjs +1 -2
- package/dist/DataList/components/DataListFilters/components/DataListSort/index.cjs +11 -11
- package/dist/DataList/components/DataListFilters/components/DataListSort/index.mjs +11 -11
- package/dist/DataList/components/DataListFilters/index.cjs +11 -11
- package/dist/DataList/components/DataListFilters/index.mjs +11 -11
- package/dist/DataList/index.cjs +11 -11
- package/dist/DataList/index.mjs +11 -11
- package/dist/DataListSort-cjs.js +5 -5
- package/dist/DataListSort-es.js +5 -5
- package/dist/FilterPicker/FilterPicker.d.ts +11 -0
- package/dist/{Combobox/Combobox.types.d.ts → FilterPicker/FilterPicker.types.d.ts} +51 -51
- package/dist/FilterPicker/FilterPickerProvider.d.ts +18 -0
- package/dist/FilterPicker/components/FilterPickerAction/FilterPickerAction.d.ts +3 -0
- package/dist/FilterPicker/components/FilterPickerAction/index.cjs +12 -0
- package/dist/FilterPicker/components/FilterPickerAction/index.d.ts +1 -0
- package/dist/FilterPicker/components/FilterPickerAction/index.mjs +6 -0
- package/dist/FilterPicker/components/FilterPickerActivator/FilterPickerActivator.d.ts +3 -0
- package/dist/{Combobox/components/ComboboxActivator → FilterPicker/components/FilterPickerActivator}/index.cjs +3 -3
- package/dist/FilterPicker/components/FilterPickerActivator/index.d.ts +1 -0
- package/dist/{Combobox/components/ComboboxActivator → FilterPicker/components/FilterPickerActivator}/index.mjs +2 -2
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerContent.d.ts +3 -0
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerContentHeader/FilterPickerContentHeader.d.ts +3 -0
- package/dist/{Combobox/components/ComboboxContent/ComboboxContentHeader → FilterPicker/components/FilterPickerContent/FilterPickerContentHeader}/index.cjs +2 -2
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerContentHeader/index.d.ts +1 -0
- package/dist/{Combobox/components/ComboboxContent/ComboboxContentHeader → FilterPicker/components/FilterPickerContent/FilterPickerContentHeader}/index.mjs +1 -1
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerContentList/FilterPickerContentList.d.ts +3 -0
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerContentList/FilterPickerContentList.module.css.d.ts +13 -0
- package/dist/{Combobox/components/ComboboxContent/ComboboxContentList → FilterPicker/components/FilterPickerContent/FilterPickerContentList}/index.cjs +5 -5
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerContentList/index.d.ts +1 -0
- package/dist/{Combobox/components/ComboboxContent/ComboboxContentList → FilterPicker/components/FilterPickerContent/FilterPickerContentList}/index.mjs +4 -4
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerContentSearch/FilterPickerContentSearch.d.ts +3 -0
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerContentSearch/index.cjs +10 -0
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerContentSearch/index.d.ts +1 -0
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerContentSearch/index.mjs +4 -0
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerLoadMore/FilterPickerLoadMore.d.ts +6 -0
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerLoadMore/index.cjs +9 -0
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerLoadMore/index.d.ts +1 -0
- package/dist/FilterPicker/components/FilterPickerContent/FilterPickerLoadMore/index.mjs +3 -0
- package/dist/{Combobox/components/ComboboxContent → FilterPicker/components/FilterPickerContent}/index.cjs +8 -8
- package/dist/FilterPicker/components/FilterPickerContent/index.d.ts +1 -0
- package/dist/{Combobox/components/ComboboxContent → FilterPicker/components/FilterPickerContent}/index.mjs +7 -7
- package/dist/FilterPicker/components/FilterPickerOption/FilterPickerOption.d.ts +3 -0
- package/dist/{Combobox/components/ComboboxOption → FilterPicker/components/FilterPickerOption}/index.cjs +3 -3
- package/dist/FilterPicker/components/FilterPickerOption/index.d.ts +1 -0
- package/dist/{Combobox/components/ComboboxOption → FilterPicker/components/FilterPickerOption}/index.mjs +2 -2
- package/dist/FilterPicker/components/FilterPickerTrigger/FilterPickerTrigger.d.ts +3 -0
- package/dist/{Combobox/components/ComboboxTrigger → FilterPicker/components/FilterPickerTrigger}/index.cjs +3 -3
- package/dist/FilterPicker/components/FilterPickerTrigger/index.d.ts +1 -0
- package/dist/{Combobox/components/ComboboxTrigger → FilterPicker/components/FilterPickerTrigger}/index.mjs +2 -2
- package/dist/FilterPicker/constants.d.ts +1 -0
- package/dist/FilterPicker/hooks/useFilterPicker.d.ts +17 -0
- package/dist/FilterPicker/hooks/useFilterPickerAccessibility.d.ts +9 -0
- package/dist/FilterPicker/hooks/useFilterPickerActivatorAccessibility.d.ts +2 -0
- package/dist/FilterPicker/hooks/useFilterPickerContent.d.ts +9 -0
- package/dist/FilterPicker/hooks/useFilterPickerValidation.d.ts +12 -0
- package/dist/FilterPicker/hooks/useMakeFilterPickerHandlers.d.ts +8 -0
- package/dist/{Combobox → FilterPicker}/index.cjs +13 -13
- package/dist/FilterPicker/index.d.ts +3 -0
- package/dist/{Combobox → FilterPicker}/index.mjs +11 -11
- package/dist/{Combobox-cjs.js → FilterPicker-cjs.js} +25 -25
- package/dist/{Combobox-es.js → FilterPicker-es.js} +25 -25
- package/dist/{ComboboxAction-cjs.js → FilterPickerAction-cjs.js} +5 -5
- package/dist/{ComboboxAction-es.js → FilterPickerAction-es.js} +5 -5
- package/dist/{ComboboxActivator-cjs.js → FilterPickerActivator-cjs.js} +8 -8
- package/dist/{ComboboxActivator-es.js → FilterPickerActivator-es.js} +9 -9
- package/dist/{ComboboxContent-cjs.js → FilterPickerContent-cjs.js} +19 -19
- package/dist/{ComboboxContent-es.js → FilterPickerContent-es.js} +20 -20
- package/dist/{ComboboxContentHeader-cjs.js → FilterPickerContentHeader-cjs.js} +4 -4
- package/dist/{ComboboxContentHeader-es.js → FilterPickerContentHeader-es.js} +4 -4
- package/dist/{ComboboxContentList-cjs.js → FilterPickerContentList-cjs.js} +7 -7
- package/dist/{ComboboxContentList-es.js → FilterPickerContentList-es.js} +7 -7
- package/dist/{ComboboxContentSearch-cjs.js → FilterPickerContentSearch-cjs.js} +4 -4
- package/dist/{ComboboxContentSearch-es.js → FilterPickerContentSearch-es.js} +4 -4
- package/dist/FilterPickerLoadMore-cjs.js +16 -0
- package/dist/{ComboboxLoadMore-es.js → FilterPickerLoadMore-es.js} +4 -4
- package/dist/{ComboboxOption-cjs.js → FilterPickerOption-cjs.js} +5 -5
- package/dist/{ComboboxOption-es.js → FilterPickerOption-es.js} +5 -5
- package/dist/FilterPickerProvider-cjs.js +13 -0
- package/dist/FilterPickerProvider-es.js +10 -0
- package/dist/{ComboboxTrigger-cjs.js → FilterPickerTrigger-cjs.js} +4 -4
- package/dist/{ComboboxTrigger-es.js → FilterPickerTrigger-es.js} +4 -4
- package/dist/InputNumberExperimental-cjs.js +3 -4
- package/dist/InputNumberExperimental-es.js +2 -3
- package/dist/Menu/index.cjs +1 -2
- package/dist/Menu/index.mjs +1 -2
- package/dist/Menu-cjs.js +11 -56
- package/dist/Menu-es.js +4 -49
- package/dist/MenuSubmenuTrigger-cjs.js +160 -345
- package/dist/MenuSubmenuTrigger-es.js +4 -186
- package/dist/Modal/index.mjs +1 -1
- package/dist/NumberFieldInput-cjs.js +3 -4
- package/dist/NumberFieldInput-es.js +2 -3
- package/dist/Page/index.cjs +1 -2
- package/dist/Page/index.mjs +1 -2
- package/dist/{DrawerRoot-cjs.js → ScrollAreaViewport-cjs.js} +1042 -3
- package/dist/{DrawerRoot-es.js → ScrollAreaViewport-es.js} +1035 -5
- package/dist/constants-cjs.js +2 -2
- package/dist/constants-es.js +2 -2
- package/dist/docs/Autocomplete/Autocomplete.md +1 -1
- package/dist/docs/Chip/Chip.md +4 -4
- package/dist/docs/DataList/DataList.md +16 -15
- package/dist/docs/{Combobox/Combobox.md → FilterPicker/FilterPicker.md} +91 -85
- package/dist/docs/Menu/Menu.md +1 -1
- package/dist/docs/MultiSelect/MultiSelect.md +1 -1
- package/dist/docs/Tabs/Tabs.md +2 -2
- package/dist/docs/index.md +1 -1
- package/dist/docs/usage-guidelines/usage-guidelines.md +5 -5
- package/dist/floating-ui.react-es.js +1 -1
- package/dist/index.cjs +14 -15
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +12 -13
- package/dist/primitives/BottomSheet/BottomSheet.d.ts +15 -16
- package/dist/primitives/BottomSheet/BottomSheet.types.d.ts +27 -0
- package/dist/primitives/BottomSheet/BottomSheet.utils.d.ts +6 -0
- package/dist/primitives/BottomSheet/index.cjs +7 -2
- package/dist/primitives/BottomSheet/index.d.ts +1 -0
- package/dist/primitives/BottomSheet/index.mjs +7 -2
- package/dist/primitives/InputNumberExperimental/index.cjs +1 -2
- package/dist/primitives/InputNumberExperimental/index.mjs +1 -2
- package/dist/primitives/index.cjs +7 -8
- package/dist/primitives/index.mjs +7 -8
- package/dist/styles.css +115 -54
- package/dist/unstyledPrimitives/index.cjs +665 -297
- package/dist/unstyledPrimitives/index.d.ts +1 -0
- package/dist/unstyledPrimitives/index.mjs +375 -8
- package/dist/useRenderElement-es.js +1 -1
- package/dist/useValueChanged-cjs.js +251 -1
- package/dist/useValueChanged-es.js +248 -2
- package/dist/utils/meta/meta.json +5 -5
- package/package.json +6 -6
- package/rollup.config.mjs +2 -2
- package/Combobox.d.ts +0 -1
- package/dist/Combobox/Combobox.d.ts +0 -11
- package/dist/Combobox/ComboboxProvider.d.ts +0 -18
- package/dist/Combobox/components/ComboboxAction/ComboboxAction.d.ts +0 -3
- package/dist/Combobox/components/ComboboxAction/index.cjs +0 -12
- package/dist/Combobox/components/ComboboxAction/index.d.ts +0 -1
- package/dist/Combobox/components/ComboboxAction/index.mjs +0 -6
- package/dist/Combobox/components/ComboboxActivator/ComboboxActivator.d.ts +0 -3
- package/dist/Combobox/components/ComboboxActivator/index.d.ts +0 -1
- package/dist/Combobox/components/ComboboxContent/ComboboxContent.d.ts +0 -3
- package/dist/Combobox/components/ComboboxContent/ComboboxContentHeader/ComboboxContentHeader.d.ts +0 -3
- package/dist/Combobox/components/ComboboxContent/ComboboxContentHeader/index.d.ts +0 -1
- package/dist/Combobox/components/ComboboxContent/ComboboxContentList/ComboboxContentList.d.ts +0 -3
- package/dist/Combobox/components/ComboboxContent/ComboboxContentList/index.d.ts +0 -1
- package/dist/Combobox/components/ComboboxContent/ComboboxContentSearch/ComboboxContentSearch.d.ts +0 -3
- package/dist/Combobox/components/ComboboxContent/ComboboxContentSearch/index.cjs +0 -10
- package/dist/Combobox/components/ComboboxContent/ComboboxContentSearch/index.d.ts +0 -1
- package/dist/Combobox/components/ComboboxContent/ComboboxContentSearch/index.mjs +0 -4
- package/dist/Combobox/components/ComboboxContent/ComboboxLoadMore/ComboboxLoadMore.d.ts +0 -6
- package/dist/Combobox/components/ComboboxContent/ComboboxLoadMore/index.cjs +0 -9
- package/dist/Combobox/components/ComboboxContent/ComboboxLoadMore/index.d.ts +0 -1
- package/dist/Combobox/components/ComboboxContent/ComboboxLoadMore/index.mjs +0 -3
- package/dist/Combobox/components/ComboboxContent/index.d.ts +0 -1
- package/dist/Combobox/components/ComboboxOption/ComboboxOption.d.ts +0 -3
- package/dist/Combobox/components/ComboboxOption/index.d.ts +0 -1
- package/dist/Combobox/components/ComboboxTrigger/ComboboxTrigger.d.ts +0 -3
- package/dist/Combobox/components/ComboboxTrigger/index.d.ts +0 -1
- package/dist/Combobox/constants.d.ts +0 -1
- package/dist/Combobox/hooks/useCombobox.d.ts +0 -17
- package/dist/Combobox/hooks/useComboboxAccessibility.d.ts +0 -9
- package/dist/Combobox/hooks/useComboboxActivatorAccessibility.d.ts +0 -2
- package/dist/Combobox/hooks/useComboboxContent.d.ts +0 -9
- package/dist/Combobox/hooks/useComboboxValidation.d.ts +0 -12
- package/dist/Combobox/hooks/useMakeComboboxHandlers.d.ts +0 -8
- package/dist/Combobox/index.d.ts +0 -3
- package/dist/ComboboxLoadMore-cjs.js +0 -16
- package/dist/ComboboxProvider-cjs.js +0 -13
- package/dist/ComboboxProvider-es.js +0 -10
- package/dist/useBaseUiId-cjs.js +0 -275
- package/dist/useBaseUiId-es.js +0 -251
|
@@ -1918,6 +1918,109 @@ function FloatingFocusManager(props) {
|
|
|
1918
1918
|
});
|
|
1919
1919
|
}
|
|
1920
1920
|
|
|
1921
|
+
/**
|
|
1922
|
+
* Opens or closes the floating element when clicking the reference element.
|
|
1923
|
+
* @see https://floating-ui.com/docs/useClick
|
|
1924
|
+
*/
|
|
1925
|
+
function useClick(context, props = {}) {
|
|
1926
|
+
const store = 'rootStore' in context ? context.rootStore : context;
|
|
1927
|
+
const dataRef = store.context.dataRef;
|
|
1928
|
+
const {
|
|
1929
|
+
enabled = true,
|
|
1930
|
+
event: eventOption = 'click',
|
|
1931
|
+
toggle = true,
|
|
1932
|
+
ignoreMouse = false,
|
|
1933
|
+
stickIfOpen = true,
|
|
1934
|
+
touchOpenDelay = 0,
|
|
1935
|
+
reason = useValueChanged.triggerPress
|
|
1936
|
+
} = props;
|
|
1937
|
+
const pointerTypeRef = React__namespace.useRef(undefined);
|
|
1938
|
+
const frame = useValueChanged.useAnimationFrame();
|
|
1939
|
+
const touchOpenTimeout = useValueChanged.useTimeout();
|
|
1940
|
+
const reference = React__namespace.useMemo(() => ({
|
|
1941
|
+
onPointerDown(event) {
|
|
1942
|
+
pointerTypeRef.current = event.pointerType;
|
|
1943
|
+
},
|
|
1944
|
+
onMouseDown(event) {
|
|
1945
|
+
const pointerType = pointerTypeRef.current;
|
|
1946
|
+
const nativeEvent = event.nativeEvent;
|
|
1947
|
+
const open = store.select('open');
|
|
1948
|
+
|
|
1949
|
+
// Ignore all buttons except for the "main" button.
|
|
1950
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
|
|
1951
|
+
if (event.button !== 0 || eventOption === 'click' || useValueChanged.isMouseLikePointerType(pointerType, true) && ignoreMouse) {
|
|
1952
|
+
return;
|
|
1953
|
+
}
|
|
1954
|
+
const openEvent = dataRef.current.openEvent;
|
|
1955
|
+
const openEventType = openEvent?.type;
|
|
1956
|
+
const hasClickedOnInactiveTrigger = store.select('domReferenceElement') !== event.currentTarget;
|
|
1957
|
+
const nextOpen = open && hasClickedOnInactiveTrigger || !(open && toggle && (openEvent && stickIfOpen ? openEventType === 'click' || openEventType === 'mousedown' : true));
|
|
1958
|
+
|
|
1959
|
+
// Animations sometimes won't run on a typeable element if using a rAF.
|
|
1960
|
+
// Focus is always set on these elements. For touch, we may delay opening.
|
|
1961
|
+
if (isTypeableElement(nativeEvent.target)) {
|
|
1962
|
+
const details = useValueChanged.createChangeEventDetails(reason, nativeEvent, nativeEvent.target);
|
|
1963
|
+
if (nextOpen && pointerType === 'touch' && touchOpenDelay > 0) {
|
|
1964
|
+
touchOpenTimeout.start(touchOpenDelay, () => {
|
|
1965
|
+
store.setOpen(true, details);
|
|
1966
|
+
});
|
|
1967
|
+
} else {
|
|
1968
|
+
store.setOpen(nextOpen, details);
|
|
1969
|
+
}
|
|
1970
|
+
return;
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
// Capture the currentTarget before the rAF.
|
|
1974
|
+
// as React sets it to null after the event handler completes.
|
|
1975
|
+
const eventCurrentTarget = event.currentTarget;
|
|
1976
|
+
|
|
1977
|
+
// Wait until focus is set on the element. This is an alternative to
|
|
1978
|
+
// `event.preventDefault()` to avoid :focus-visible from appearing when using a pointer.
|
|
1979
|
+
frame.request(() => {
|
|
1980
|
+
const details = useValueChanged.createChangeEventDetails(reason, nativeEvent, eventCurrentTarget);
|
|
1981
|
+
if (nextOpen && pointerType === 'touch' && touchOpenDelay > 0) {
|
|
1982
|
+
touchOpenTimeout.start(touchOpenDelay, () => {
|
|
1983
|
+
store.setOpen(true, details);
|
|
1984
|
+
});
|
|
1985
|
+
} else {
|
|
1986
|
+
store.setOpen(nextOpen, details);
|
|
1987
|
+
}
|
|
1988
|
+
});
|
|
1989
|
+
},
|
|
1990
|
+
onClick(event) {
|
|
1991
|
+
if (eventOption === 'mousedown-only') {
|
|
1992
|
+
return;
|
|
1993
|
+
}
|
|
1994
|
+
const pointerType = pointerTypeRef.current;
|
|
1995
|
+
if (eventOption === 'mousedown' && pointerType) {
|
|
1996
|
+
pointerTypeRef.current = undefined;
|
|
1997
|
+
return;
|
|
1998
|
+
}
|
|
1999
|
+
if (useValueChanged.isMouseLikePointerType(pointerType, true) && ignoreMouse) {
|
|
2000
|
+
return;
|
|
2001
|
+
}
|
|
2002
|
+
const open = store.select('open');
|
|
2003
|
+
const openEvent = dataRef.current.openEvent;
|
|
2004
|
+
const hasClickedOnInactiveTrigger = store.select('domReferenceElement') !== event.currentTarget;
|
|
2005
|
+
const nextOpen = open && hasClickedOnInactiveTrigger || !(open && toggle && (openEvent && stickIfOpen ? useValueChanged.isClickLikeEvent(openEvent) : true));
|
|
2006
|
+
const details = useValueChanged.createChangeEventDetails(reason, event.nativeEvent, event.currentTarget);
|
|
2007
|
+
if (nextOpen && pointerType === 'touch' && touchOpenDelay > 0) {
|
|
2008
|
+
touchOpenTimeout.start(touchOpenDelay, () => {
|
|
2009
|
+
store.setOpen(true, details);
|
|
2010
|
+
});
|
|
2011
|
+
} else {
|
|
2012
|
+
store.setOpen(nextOpen, details);
|
|
2013
|
+
}
|
|
2014
|
+
},
|
|
2015
|
+
onKeyDown() {
|
|
2016
|
+
pointerTypeRef.current = undefined;
|
|
2017
|
+
}
|
|
2018
|
+
}), [dataRef, eventOption, ignoreMouse, store, stickIfOpen, toggle, frame, touchOpenTimeout, touchOpenDelay, reason]);
|
|
2019
|
+
return React__namespace.useMemo(() => enabled ? {
|
|
2020
|
+
reference
|
|
2021
|
+
} : useRenderElement.EMPTY_OBJECT, [enabled, reference]);
|
|
2022
|
+
}
|
|
2023
|
+
|
|
1921
2024
|
const bubbleHandlerKeys = {
|
|
1922
2025
|
intentional: 'onClick',
|
|
1923
2026
|
sloppy: 'onPointerDown'
|
|
@@ -4608,7 +4711,7 @@ let drawerSwipeVarsRegistered = false;
|
|
|
4608
4711
|
* See https://motion.dev/blog/web-animation-performance-tier-list
|
|
4609
4712
|
* under the "Improving CSS variable performance" section.
|
|
4610
4713
|
*/
|
|
4611
|
-
function removeCSSVariableInheritance() {
|
|
4714
|
+
function removeCSSVariableInheritance$1() {
|
|
4612
4715
|
if (drawerSwipeVarsRegistered) {
|
|
4613
4716
|
return;
|
|
4614
4717
|
}
|
|
@@ -4773,7 +4876,7 @@ const DrawerPopup = /*#__PURE__*/React__namespace.forwardRef(function DrawerPopu
|
|
|
4773
4876
|
if (!popupElement) {
|
|
4774
4877
|
return undefined;
|
|
4775
4878
|
}
|
|
4776
|
-
removeCSSVariableInheritance();
|
|
4879
|
+
removeCSSVariableInheritance$1();
|
|
4777
4880
|
measureHeight();
|
|
4778
4881
|
if (typeof ResizeObserver !== 'function') {
|
|
4779
4882
|
return undefined;
|
|
@@ -5590,6 +5693,66 @@ function DialogRoot(props) {
|
|
|
5590
5693
|
});
|
|
5591
5694
|
}
|
|
5592
5695
|
|
|
5696
|
+
/**
|
|
5697
|
+
* A button that opens the dialog.
|
|
5698
|
+
* Renders a `<button>` element.
|
|
5699
|
+
*
|
|
5700
|
+
* Documentation: [Base UI Dialog](https://base-ui.com/react/components/dialog)
|
|
5701
|
+
*/
|
|
5702
|
+
const DialogTrigger = /*#__PURE__*/React__namespace.forwardRef(function DialogTrigger(componentProps, forwardedRef) {
|
|
5703
|
+
const {
|
|
5704
|
+
render,
|
|
5705
|
+
className,
|
|
5706
|
+
disabled = false,
|
|
5707
|
+
nativeButton = true,
|
|
5708
|
+
id: idProp,
|
|
5709
|
+
payload,
|
|
5710
|
+
handle,
|
|
5711
|
+
...elementProps
|
|
5712
|
+
} = componentProps;
|
|
5713
|
+
const dialogRootContext = useDialogRootContext(true);
|
|
5714
|
+
const store = handle?.store ?? dialogRootContext?.store;
|
|
5715
|
+
if (!store) {
|
|
5716
|
+
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: <Dialog.Trigger> must be used within <Dialog.Root> or provided with a handle.' : useRenderElement.formatErrorMessage(79));
|
|
5717
|
+
}
|
|
5718
|
+
const thisTriggerId = useValueChanged.useBaseUiId(idProp);
|
|
5719
|
+
const floatingContext = store.useState('floatingRootContext');
|
|
5720
|
+
const isOpenedByThisTrigger = store.useState('isOpenedByTrigger', thisTriggerId);
|
|
5721
|
+
const triggerElementRef = React__namespace.useRef(null);
|
|
5722
|
+
const {
|
|
5723
|
+
registerTrigger,
|
|
5724
|
+
isMountedByThisTrigger
|
|
5725
|
+
} = useTriggerDataForwarding(thisTriggerId, triggerElementRef, store, {
|
|
5726
|
+
payload
|
|
5727
|
+
});
|
|
5728
|
+
const {
|
|
5729
|
+
getButtonProps,
|
|
5730
|
+
buttonRef
|
|
5731
|
+
} = useValueChanged.useButton({
|
|
5732
|
+
disabled,
|
|
5733
|
+
native: nativeButton
|
|
5734
|
+
});
|
|
5735
|
+
const click = useClick(floatingContext, {
|
|
5736
|
+
enabled: floatingContext != null
|
|
5737
|
+
});
|
|
5738
|
+
const localInteractionProps = useInteractions([click]);
|
|
5739
|
+
const state = {
|
|
5740
|
+
disabled,
|
|
5741
|
+
open: isOpenedByThisTrigger
|
|
5742
|
+
};
|
|
5743
|
+
const rootTriggerProps = store.useState('triggerProps', isMountedByThisTrigger);
|
|
5744
|
+
return useRenderElement.useRenderElement('button', componentProps, {
|
|
5745
|
+
state,
|
|
5746
|
+
ref: [buttonRef, forwardedRef, registerTrigger, triggerElementRef],
|
|
5747
|
+
props: [localInteractionProps.getReferenceProps(), rootTriggerProps, {
|
|
5748
|
+
[CLICK_TRIGGER_IDENTIFIER]: '',
|
|
5749
|
+
id: thisTriggerId
|
|
5750
|
+
}, elementProps, getButtonProps],
|
|
5751
|
+
stateAttributesMapping: triggerOpenStateMapping
|
|
5752
|
+
});
|
|
5753
|
+
});
|
|
5754
|
+
if (process.env.NODE_ENV !== "production") DialogTrigger.displayName = "DialogTrigger";
|
|
5755
|
+
|
|
5593
5756
|
var _DrawerProviderReport, _DrawerProviderReport2;
|
|
5594
5757
|
/**
|
|
5595
5758
|
* Groups all parts of the drawer.
|
|
@@ -5809,12 +5972,878 @@ function DrawerProviderReporter() {
|
|
|
5809
5972
|
return null;
|
|
5810
5973
|
}
|
|
5811
5974
|
|
|
5975
|
+
/**
|
|
5976
|
+
* A button that opens the drawer.
|
|
5977
|
+
* Renders a `<button>` element.
|
|
5978
|
+
*
|
|
5979
|
+
* Documentation: [Base UI Drawer](https://base-ui.com/react/components/drawer)
|
|
5980
|
+
*/
|
|
5981
|
+
const DrawerTrigger = DialogTrigger;
|
|
5982
|
+
|
|
5983
|
+
/**
|
|
5984
|
+
* @internal
|
|
5985
|
+
*/
|
|
5986
|
+
const DirectionContext = /*#__PURE__*/React__namespace.createContext(undefined);
|
|
5987
|
+
if (process.env.NODE_ENV !== "production") DirectionContext.displayName = "DirectionContext";
|
|
5988
|
+
function useDirection() {
|
|
5989
|
+
const context = React__namespace.useContext(DirectionContext);
|
|
5990
|
+
return context?.direction ?? 'ltr';
|
|
5991
|
+
}
|
|
5992
|
+
|
|
5993
|
+
const ScrollAreaRootContext = /*#__PURE__*/React__namespace.createContext(undefined);
|
|
5994
|
+
if (process.env.NODE_ENV !== "production") ScrollAreaRootContext.displayName = "ScrollAreaRootContext";
|
|
5995
|
+
function useScrollAreaRootContext() {
|
|
5996
|
+
const context = React__namespace.useContext(ScrollAreaRootContext);
|
|
5997
|
+
if (context === undefined) {
|
|
5998
|
+
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: ScrollAreaRootContext is missing. ScrollArea parts must be placed within <ScrollArea.Root>.' : useRenderElement.formatErrorMessage(53));
|
|
5999
|
+
}
|
|
6000
|
+
return context;
|
|
6001
|
+
}
|
|
6002
|
+
|
|
6003
|
+
let ScrollAreaRootCssVars = /*#__PURE__*/function (ScrollAreaRootCssVars) {
|
|
6004
|
+
/**
|
|
6005
|
+
* The scroll area's corner height.
|
|
6006
|
+
* @type {number}
|
|
6007
|
+
*/
|
|
6008
|
+
ScrollAreaRootCssVars["scrollAreaCornerHeight"] = "--scroll-area-corner-height";
|
|
6009
|
+
/**
|
|
6010
|
+
* The scroll area's corner width.
|
|
6011
|
+
* @type {number}
|
|
6012
|
+
*/
|
|
6013
|
+
ScrollAreaRootCssVars["scrollAreaCornerWidth"] = "--scroll-area-corner-width";
|
|
6014
|
+
return ScrollAreaRootCssVars;
|
|
6015
|
+
}({});
|
|
6016
|
+
|
|
6017
|
+
const SCROLL_TIMEOUT = 500;
|
|
6018
|
+
const MIN_THUMB_SIZE = 16;
|
|
6019
|
+
|
|
6020
|
+
function getOffset(element, prop, axis) {
|
|
6021
|
+
if (!element) {
|
|
6022
|
+
return 0;
|
|
6023
|
+
}
|
|
6024
|
+
const styles = getComputedStyle(element);
|
|
6025
|
+
const propAxis = axis === 'x' ? 'Inline' : 'Block';
|
|
6026
|
+
|
|
6027
|
+
// Safari misreports `marginInlineEnd` in RTL.
|
|
6028
|
+
// We have to assume the start/end values are symmetrical, which is likely.
|
|
6029
|
+
if (axis === 'x' && prop === 'margin') {
|
|
6030
|
+
return parseFloat(styles[`${prop}InlineStart`]) * 2;
|
|
6031
|
+
}
|
|
6032
|
+
return parseFloat(styles[`${prop}${propAxis}Start`]) + parseFloat(styles[`${prop}${propAxis}End`]);
|
|
6033
|
+
}
|
|
6034
|
+
|
|
6035
|
+
let ScrollAreaScrollbarDataAttributes = /*#__PURE__*/function (ScrollAreaScrollbarDataAttributes) {
|
|
6036
|
+
/**
|
|
6037
|
+
* Indicates the orientation of the scrollbar.
|
|
6038
|
+
* @type {'horizontal' | 'vertical'}
|
|
6039
|
+
*/
|
|
6040
|
+
ScrollAreaScrollbarDataAttributes["orientation"] = "data-orientation";
|
|
6041
|
+
/**
|
|
6042
|
+
* Present when the pointer is over the scroll area.
|
|
6043
|
+
*/
|
|
6044
|
+
ScrollAreaScrollbarDataAttributes["hovering"] = "data-hovering";
|
|
6045
|
+
/**
|
|
6046
|
+
* Present when the user scrolls inside the scroll area.
|
|
6047
|
+
*/
|
|
6048
|
+
ScrollAreaScrollbarDataAttributes["scrolling"] = "data-scrolling";
|
|
6049
|
+
/**
|
|
6050
|
+
* Present when the scroll area content is wider than the viewport.
|
|
6051
|
+
*/
|
|
6052
|
+
ScrollAreaScrollbarDataAttributes["hasOverflowX"] = "data-has-overflow-x";
|
|
6053
|
+
/**
|
|
6054
|
+
* Present when the scroll area content is taller than the viewport.
|
|
6055
|
+
*/
|
|
6056
|
+
ScrollAreaScrollbarDataAttributes["hasOverflowY"] = "data-has-overflow-y";
|
|
6057
|
+
/**
|
|
6058
|
+
* Present when there is overflow on the horizontal start side.
|
|
6059
|
+
*/
|
|
6060
|
+
ScrollAreaScrollbarDataAttributes["overflowXStart"] = "data-overflow-x-start";
|
|
6061
|
+
/**
|
|
6062
|
+
* Present when there is overflow on the horizontal end side.
|
|
6063
|
+
*/
|
|
6064
|
+
ScrollAreaScrollbarDataAttributes["overflowXEnd"] = "data-overflow-x-end";
|
|
6065
|
+
/**
|
|
6066
|
+
* Present when there is overflow on the vertical start side.
|
|
6067
|
+
*/
|
|
6068
|
+
ScrollAreaScrollbarDataAttributes["overflowYStart"] = "data-overflow-y-start";
|
|
6069
|
+
/**
|
|
6070
|
+
* Present when there is overflow on the vertical end side.
|
|
6071
|
+
*/
|
|
6072
|
+
ScrollAreaScrollbarDataAttributes["overflowYEnd"] = "data-overflow-y-end";
|
|
6073
|
+
return ScrollAreaScrollbarDataAttributes;
|
|
6074
|
+
}({});
|
|
6075
|
+
|
|
6076
|
+
const DISABLE_SCROLLBAR_CLASS_NAME = 'base-ui-disable-scrollbar';
|
|
6077
|
+
const styleDisableScrollbar = {
|
|
6078
|
+
className: DISABLE_SCROLLBAR_CLASS_NAME,
|
|
6079
|
+
getElement(nonce) {
|
|
6080
|
+
return /*#__PURE__*/jsxRuntime.jsx("style", {
|
|
6081
|
+
nonce: nonce,
|
|
6082
|
+
href: DISABLE_SCROLLBAR_CLASS_NAME,
|
|
6083
|
+
precedence: "base-ui:low",
|
|
6084
|
+
children: `.${DISABLE_SCROLLBAR_CLASS_NAME}{scrollbar-width:none}.${DISABLE_SCROLLBAR_CLASS_NAME}::-webkit-scrollbar{display:none}`
|
|
6085
|
+
});
|
|
6086
|
+
}
|
|
6087
|
+
};
|
|
6088
|
+
if (process.env.NODE_ENV !== "production") styleDisableScrollbar.getElement.displayName = "styleDisableScrollbar.getElement";
|
|
6089
|
+
|
|
6090
|
+
let ScrollAreaRootDataAttributes = /*#__PURE__*/function (ScrollAreaRootDataAttributes) {
|
|
6091
|
+
/**
|
|
6092
|
+
* Present when the user scrolls inside the scroll area.
|
|
6093
|
+
*/
|
|
6094
|
+
ScrollAreaRootDataAttributes["scrolling"] = "data-scrolling";
|
|
6095
|
+
/**
|
|
6096
|
+
* Present when the scroll area content is wider than the viewport.
|
|
6097
|
+
*/
|
|
6098
|
+
ScrollAreaRootDataAttributes["hasOverflowX"] = "data-has-overflow-x";
|
|
6099
|
+
/**
|
|
6100
|
+
* Present when the scroll area content is taller than the viewport.
|
|
6101
|
+
*/
|
|
6102
|
+
ScrollAreaRootDataAttributes["hasOverflowY"] = "data-has-overflow-y";
|
|
6103
|
+
/**
|
|
6104
|
+
* Present when there is overflow on the horizontal start side.
|
|
6105
|
+
*/
|
|
6106
|
+
ScrollAreaRootDataAttributes["overflowXStart"] = "data-overflow-x-start";
|
|
6107
|
+
/**
|
|
6108
|
+
* Present when there is overflow on the horizontal end side.
|
|
6109
|
+
*/
|
|
6110
|
+
ScrollAreaRootDataAttributes["overflowXEnd"] = "data-overflow-x-end";
|
|
6111
|
+
/**
|
|
6112
|
+
* Present when there is overflow on the vertical start side.
|
|
6113
|
+
*/
|
|
6114
|
+
ScrollAreaRootDataAttributes["overflowYStart"] = "data-overflow-y-start";
|
|
6115
|
+
/**
|
|
6116
|
+
* Present when there is overflow on the vertical end side.
|
|
6117
|
+
*/
|
|
6118
|
+
ScrollAreaRootDataAttributes["overflowYEnd"] = "data-overflow-y-end";
|
|
6119
|
+
return ScrollAreaRootDataAttributes;
|
|
6120
|
+
}({});
|
|
6121
|
+
|
|
6122
|
+
const scrollAreaStateAttributesMapping = {
|
|
6123
|
+
hasOverflowX: value => value ? {
|
|
6124
|
+
[ScrollAreaRootDataAttributes.hasOverflowX]: ''
|
|
6125
|
+
} : null,
|
|
6126
|
+
hasOverflowY: value => value ? {
|
|
6127
|
+
[ScrollAreaRootDataAttributes.hasOverflowY]: ''
|
|
6128
|
+
} : null,
|
|
6129
|
+
overflowXStart: value => value ? {
|
|
6130
|
+
[ScrollAreaRootDataAttributes.overflowXStart]: ''
|
|
6131
|
+
} : null,
|
|
6132
|
+
overflowXEnd: value => value ? {
|
|
6133
|
+
[ScrollAreaRootDataAttributes.overflowXEnd]: ''
|
|
6134
|
+
} : null,
|
|
6135
|
+
overflowYStart: value => value ? {
|
|
6136
|
+
[ScrollAreaRootDataAttributes.overflowYStart]: ''
|
|
6137
|
+
} : null,
|
|
6138
|
+
overflowYEnd: value => value ? {
|
|
6139
|
+
[ScrollAreaRootDataAttributes.overflowYEnd]: ''
|
|
6140
|
+
} : null,
|
|
6141
|
+
cornerHidden: () => null
|
|
6142
|
+
};
|
|
6143
|
+
|
|
6144
|
+
/**
|
|
6145
|
+
* @internal
|
|
6146
|
+
*/
|
|
6147
|
+
const CSPContext = /*#__PURE__*/React__namespace.createContext(undefined);
|
|
6148
|
+
if (process.env.NODE_ENV !== "production") CSPContext.displayName = "CSPContext";
|
|
6149
|
+
const DEFAULT_CSP_CONTEXT_VALUE = {
|
|
6150
|
+
disableStyleElements: false
|
|
6151
|
+
};
|
|
6152
|
+
|
|
6153
|
+
/**
|
|
6154
|
+
* @internal
|
|
6155
|
+
*/
|
|
6156
|
+
function useCSPContext() {
|
|
6157
|
+
return React__namespace.useContext(CSPContext) ?? DEFAULT_CSP_CONTEXT_VALUE;
|
|
6158
|
+
}
|
|
6159
|
+
|
|
6160
|
+
const DEFAULT_COORDS = {
|
|
6161
|
+
x: 0,
|
|
6162
|
+
y: 0
|
|
6163
|
+
};
|
|
6164
|
+
const DEFAULT_SIZE = {
|
|
6165
|
+
width: 0,
|
|
6166
|
+
height: 0
|
|
6167
|
+
};
|
|
6168
|
+
const DEFAULT_OVERFLOW_EDGES = {
|
|
6169
|
+
xStart: false,
|
|
6170
|
+
xEnd: false,
|
|
6171
|
+
yStart: false,
|
|
6172
|
+
yEnd: false
|
|
6173
|
+
};
|
|
6174
|
+
const DEFAULT_HIDDEN_STATE = {
|
|
6175
|
+
x: true,
|
|
6176
|
+
y: true,
|
|
6177
|
+
corner: true
|
|
6178
|
+
};
|
|
6179
|
+
/**
|
|
6180
|
+
* Groups all parts of the scroll area.
|
|
6181
|
+
* Renders a `<div>` element.
|
|
6182
|
+
*
|
|
6183
|
+
* Documentation: [Base UI Scroll Area](https://base-ui.com/react/components/scroll-area)
|
|
6184
|
+
*/
|
|
6185
|
+
const ScrollAreaRoot = /*#__PURE__*/React__namespace.forwardRef(function ScrollAreaRoot(componentProps, forwardedRef) {
|
|
6186
|
+
const {
|
|
6187
|
+
render,
|
|
6188
|
+
className,
|
|
6189
|
+
overflowEdgeThreshold: overflowEdgeThresholdProp,
|
|
6190
|
+
...elementProps
|
|
6191
|
+
} = componentProps;
|
|
6192
|
+
const overflowEdgeThreshold = normalizeOverflowEdgeThreshold(overflowEdgeThresholdProp);
|
|
6193
|
+
const rootId = useValueChanged.useBaseUiId();
|
|
6194
|
+
const scrollYTimeout = useValueChanged.useTimeout();
|
|
6195
|
+
const scrollXTimeout = useValueChanged.useTimeout();
|
|
6196
|
+
const {
|
|
6197
|
+
nonce,
|
|
6198
|
+
disableStyleElements
|
|
6199
|
+
} = useCSPContext();
|
|
6200
|
+
const [hovering, setHovering] = React__namespace.useState(false);
|
|
6201
|
+
const [scrollingX, setScrollingX] = React__namespace.useState(false);
|
|
6202
|
+
const [scrollingY, setScrollingY] = React__namespace.useState(false);
|
|
6203
|
+
const [touchModality, setTouchModality] = React__namespace.useState(false);
|
|
6204
|
+
const [hasMeasuredScrollbar, setHasMeasuredScrollbar] = React__namespace.useState(false);
|
|
6205
|
+
const [cornerSize, setCornerSize] = React__namespace.useState(DEFAULT_SIZE);
|
|
6206
|
+
const [thumbSize, setThumbSize] = React__namespace.useState(DEFAULT_SIZE);
|
|
6207
|
+
const [overflowEdges, setOverflowEdges] = React__namespace.useState(DEFAULT_OVERFLOW_EDGES);
|
|
6208
|
+
const [hiddenState, setHiddenState] = React__namespace.useState(DEFAULT_HIDDEN_STATE);
|
|
6209
|
+
const rootRef = React__namespace.useRef(null);
|
|
6210
|
+
const viewportRef = React__namespace.useRef(null);
|
|
6211
|
+
const scrollbarYRef = React__namespace.useRef(null);
|
|
6212
|
+
const scrollbarXRef = React__namespace.useRef(null);
|
|
6213
|
+
const thumbYRef = React__namespace.useRef(null);
|
|
6214
|
+
const thumbXRef = React__namespace.useRef(null);
|
|
6215
|
+
const cornerRef = React__namespace.useRef(null);
|
|
6216
|
+
const thumbDraggingRef = React__namespace.useRef(false);
|
|
6217
|
+
const startYRef = React__namespace.useRef(0);
|
|
6218
|
+
const startXRef = React__namespace.useRef(0);
|
|
6219
|
+
const startScrollTopRef = React__namespace.useRef(0);
|
|
6220
|
+
const startScrollLeftRef = React__namespace.useRef(0);
|
|
6221
|
+
const currentOrientationRef = React__namespace.useRef('vertical');
|
|
6222
|
+
const scrollPositionRef = React__namespace.useRef(DEFAULT_COORDS);
|
|
6223
|
+
const handleScroll = useValueChanged.useStableCallback(scrollPosition => {
|
|
6224
|
+
const offsetX = scrollPosition.x - scrollPositionRef.current.x;
|
|
6225
|
+
const offsetY = scrollPosition.y - scrollPositionRef.current.y;
|
|
6226
|
+
scrollPositionRef.current = scrollPosition;
|
|
6227
|
+
if (offsetY !== 0) {
|
|
6228
|
+
setScrollingY(true);
|
|
6229
|
+
scrollYTimeout.start(SCROLL_TIMEOUT, () => {
|
|
6230
|
+
setScrollingY(false);
|
|
6231
|
+
});
|
|
6232
|
+
}
|
|
6233
|
+
if (offsetX !== 0) {
|
|
6234
|
+
setScrollingX(true);
|
|
6235
|
+
scrollXTimeout.start(SCROLL_TIMEOUT, () => {
|
|
6236
|
+
setScrollingX(false);
|
|
6237
|
+
});
|
|
6238
|
+
}
|
|
6239
|
+
});
|
|
6240
|
+
const handlePointerDown = useValueChanged.useStableCallback(event => {
|
|
6241
|
+
if (event.button !== 0) {
|
|
6242
|
+
return;
|
|
6243
|
+
}
|
|
6244
|
+
thumbDraggingRef.current = true;
|
|
6245
|
+
startYRef.current = event.clientY;
|
|
6246
|
+
startXRef.current = event.clientX;
|
|
6247
|
+
currentOrientationRef.current = event.currentTarget.getAttribute(ScrollAreaScrollbarDataAttributes.orientation);
|
|
6248
|
+
if (viewportRef.current) {
|
|
6249
|
+
startScrollTopRef.current = viewportRef.current.scrollTop;
|
|
6250
|
+
startScrollLeftRef.current = viewportRef.current.scrollLeft;
|
|
6251
|
+
}
|
|
6252
|
+
if (thumbYRef.current && currentOrientationRef.current === 'vertical') {
|
|
6253
|
+
thumbYRef.current.setPointerCapture(event.pointerId);
|
|
6254
|
+
}
|
|
6255
|
+
if (thumbXRef.current && currentOrientationRef.current === 'horizontal') {
|
|
6256
|
+
thumbXRef.current.setPointerCapture(event.pointerId);
|
|
6257
|
+
}
|
|
6258
|
+
});
|
|
6259
|
+
const handlePointerMove = useValueChanged.useStableCallback(event => {
|
|
6260
|
+
if (!thumbDraggingRef.current) {
|
|
6261
|
+
return;
|
|
6262
|
+
}
|
|
6263
|
+
const deltaY = event.clientY - startYRef.current;
|
|
6264
|
+
const deltaX = event.clientX - startXRef.current;
|
|
6265
|
+
if (viewportRef.current) {
|
|
6266
|
+
const scrollableContentHeight = viewportRef.current.scrollHeight;
|
|
6267
|
+
const viewportHeight = viewportRef.current.clientHeight;
|
|
6268
|
+
const scrollableContentWidth = viewportRef.current.scrollWidth;
|
|
6269
|
+
const viewportWidth = viewportRef.current.clientWidth;
|
|
6270
|
+
if (thumbYRef.current && scrollbarYRef.current && currentOrientationRef.current === 'vertical') {
|
|
6271
|
+
const scrollbarYOffset = getOffset(scrollbarYRef.current, 'padding', 'y');
|
|
6272
|
+
const thumbYOffset = getOffset(thumbYRef.current, 'margin', 'y');
|
|
6273
|
+
const thumbHeight = thumbYRef.current.offsetHeight;
|
|
6274
|
+
const maxThumbOffsetY = scrollbarYRef.current.offsetHeight - thumbHeight - scrollbarYOffset - thumbYOffset;
|
|
6275
|
+
const scrollRatioY = deltaY / maxThumbOffsetY;
|
|
6276
|
+
viewportRef.current.scrollTop = startScrollTopRef.current + scrollRatioY * (scrollableContentHeight - viewportHeight);
|
|
6277
|
+
event.preventDefault();
|
|
6278
|
+
setScrollingY(true);
|
|
6279
|
+
scrollYTimeout.start(SCROLL_TIMEOUT, () => {
|
|
6280
|
+
setScrollingY(false);
|
|
6281
|
+
});
|
|
6282
|
+
}
|
|
6283
|
+
if (thumbXRef.current && scrollbarXRef.current && currentOrientationRef.current === 'horizontal') {
|
|
6284
|
+
const scrollbarXOffset = getOffset(scrollbarXRef.current, 'padding', 'x');
|
|
6285
|
+
const thumbXOffset = getOffset(thumbXRef.current, 'margin', 'x');
|
|
6286
|
+
const thumbWidth = thumbXRef.current.offsetWidth;
|
|
6287
|
+
const maxThumbOffsetX = scrollbarXRef.current.offsetWidth - thumbWidth - scrollbarXOffset - thumbXOffset;
|
|
6288
|
+
const scrollRatioX = deltaX / maxThumbOffsetX;
|
|
6289
|
+
viewportRef.current.scrollLeft = startScrollLeftRef.current + scrollRatioX * (scrollableContentWidth - viewportWidth);
|
|
6290
|
+
event.preventDefault();
|
|
6291
|
+
setScrollingX(true);
|
|
6292
|
+
scrollXTimeout.start(SCROLL_TIMEOUT, () => {
|
|
6293
|
+
setScrollingX(false);
|
|
6294
|
+
});
|
|
6295
|
+
}
|
|
6296
|
+
}
|
|
6297
|
+
});
|
|
6298
|
+
const handlePointerUp = useValueChanged.useStableCallback(event => {
|
|
6299
|
+
thumbDraggingRef.current = false;
|
|
6300
|
+
if (thumbYRef.current && currentOrientationRef.current === 'vertical') {
|
|
6301
|
+
thumbYRef.current.releasePointerCapture(event.pointerId);
|
|
6302
|
+
}
|
|
6303
|
+
if (thumbXRef.current && currentOrientationRef.current === 'horizontal') {
|
|
6304
|
+
thumbXRef.current.releasePointerCapture(event.pointerId);
|
|
6305
|
+
}
|
|
6306
|
+
});
|
|
6307
|
+
function handleTouchModalityChange(event) {
|
|
6308
|
+
setTouchModality(event.pointerType === 'touch');
|
|
6309
|
+
}
|
|
6310
|
+
function handlePointerEnterOrMove(event) {
|
|
6311
|
+
handleTouchModalityChange(event);
|
|
6312
|
+
if (event.pointerType !== 'touch') {
|
|
6313
|
+
const isTargetRootChild = contains(rootRef.current, event.target);
|
|
6314
|
+
setHovering(isTargetRootChild);
|
|
6315
|
+
}
|
|
6316
|
+
}
|
|
6317
|
+
const state = React__namespace.useMemo(() => ({
|
|
6318
|
+
scrolling: scrollingX || scrollingY,
|
|
6319
|
+
hasOverflowX: !hiddenState.x,
|
|
6320
|
+
hasOverflowY: !hiddenState.y,
|
|
6321
|
+
overflowXStart: overflowEdges.xStart,
|
|
6322
|
+
overflowXEnd: overflowEdges.xEnd,
|
|
6323
|
+
overflowYStart: overflowEdges.yStart,
|
|
6324
|
+
overflowYEnd: overflowEdges.yEnd,
|
|
6325
|
+
cornerHidden: hiddenState.corner
|
|
6326
|
+
}), [scrollingX, scrollingY, hiddenState.x, hiddenState.y, hiddenState.corner, overflowEdges]);
|
|
6327
|
+
const props = {
|
|
6328
|
+
role: 'presentation',
|
|
6329
|
+
onPointerEnter: handlePointerEnterOrMove,
|
|
6330
|
+
onPointerMove: handlePointerEnterOrMove,
|
|
6331
|
+
onPointerDown: handleTouchModalityChange,
|
|
6332
|
+
onPointerLeave() {
|
|
6333
|
+
setHovering(false);
|
|
6334
|
+
},
|
|
6335
|
+
style: {
|
|
6336
|
+
position: 'relative',
|
|
6337
|
+
[ScrollAreaRootCssVars.scrollAreaCornerHeight]: `${cornerSize.height}px`,
|
|
6338
|
+
[ScrollAreaRootCssVars.scrollAreaCornerWidth]: `${cornerSize.width}px`
|
|
6339
|
+
}
|
|
6340
|
+
};
|
|
6341
|
+
const element = useRenderElement.useRenderElement('div', componentProps, {
|
|
6342
|
+
state,
|
|
6343
|
+
ref: [forwardedRef, rootRef],
|
|
6344
|
+
props: [props, elementProps],
|
|
6345
|
+
stateAttributesMapping: scrollAreaStateAttributesMapping
|
|
6346
|
+
});
|
|
6347
|
+
const contextValue = React__namespace.useMemo(() => ({
|
|
6348
|
+
handlePointerDown,
|
|
6349
|
+
handlePointerMove,
|
|
6350
|
+
handlePointerUp,
|
|
6351
|
+
handleScroll,
|
|
6352
|
+
cornerSize,
|
|
6353
|
+
setCornerSize,
|
|
6354
|
+
thumbSize,
|
|
6355
|
+
setThumbSize,
|
|
6356
|
+
hasMeasuredScrollbar,
|
|
6357
|
+
setHasMeasuredScrollbar,
|
|
6358
|
+
touchModality,
|
|
6359
|
+
cornerRef,
|
|
6360
|
+
scrollingX,
|
|
6361
|
+
setScrollingX,
|
|
6362
|
+
scrollingY,
|
|
6363
|
+
setScrollingY,
|
|
6364
|
+
hovering,
|
|
6365
|
+
setHovering,
|
|
6366
|
+
viewportRef,
|
|
6367
|
+
rootRef,
|
|
6368
|
+
scrollbarYRef,
|
|
6369
|
+
scrollbarXRef,
|
|
6370
|
+
thumbYRef,
|
|
6371
|
+
thumbXRef,
|
|
6372
|
+
rootId,
|
|
6373
|
+
hiddenState,
|
|
6374
|
+
setHiddenState,
|
|
6375
|
+
overflowEdges,
|
|
6376
|
+
setOverflowEdges,
|
|
6377
|
+
viewportState: state,
|
|
6378
|
+
overflowEdgeThreshold
|
|
6379
|
+
}), [handlePointerDown, handlePointerMove, handlePointerUp, handleScroll, cornerSize, thumbSize, hasMeasuredScrollbar, touchModality, scrollingX, setScrollingX, scrollingY, setScrollingY, hovering, setHovering, rootId, hiddenState, overflowEdges, state, overflowEdgeThreshold]);
|
|
6380
|
+
return /*#__PURE__*/jsxRuntime.jsxs(ScrollAreaRootContext.Provider, {
|
|
6381
|
+
value: contextValue,
|
|
6382
|
+
children: [!disableStyleElements && styleDisableScrollbar.getElement(nonce), element]
|
|
6383
|
+
});
|
|
6384
|
+
});
|
|
6385
|
+
if (process.env.NODE_ENV !== "production") ScrollAreaRoot.displayName = "ScrollAreaRoot";
|
|
6386
|
+
function normalizeOverflowEdgeThreshold(threshold) {
|
|
6387
|
+
if (typeof threshold === 'number') {
|
|
6388
|
+
const value = Math.max(0, threshold);
|
|
6389
|
+
return {
|
|
6390
|
+
xStart: value,
|
|
6391
|
+
xEnd: value,
|
|
6392
|
+
yStart: value,
|
|
6393
|
+
yEnd: value
|
|
6394
|
+
};
|
|
6395
|
+
}
|
|
6396
|
+
return {
|
|
6397
|
+
xStart: Math.max(0, threshold?.xStart || 0),
|
|
6398
|
+
xEnd: Math.max(0, threshold?.xEnd || 0),
|
|
6399
|
+
yStart: Math.max(0, threshold?.yStart || 0),
|
|
6400
|
+
yEnd: Math.max(0, threshold?.yEnd || 0)
|
|
6401
|
+
};
|
|
6402
|
+
}
|
|
6403
|
+
|
|
6404
|
+
const ScrollAreaViewportContext = /*#__PURE__*/React__namespace.createContext(undefined);
|
|
6405
|
+
if (process.env.NODE_ENV !== "production") ScrollAreaViewportContext.displayName = "ScrollAreaViewportContext";
|
|
6406
|
+
function useScrollAreaViewportContext() {
|
|
6407
|
+
const context = React__namespace.useContext(ScrollAreaViewportContext);
|
|
6408
|
+
if (context === undefined) {
|
|
6409
|
+
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: ScrollAreaViewportContext missing. ScrollAreaViewport parts must be placed within <ScrollArea.Viewport>.' : useRenderElement.formatErrorMessage(55));
|
|
6410
|
+
}
|
|
6411
|
+
return context;
|
|
6412
|
+
}
|
|
6413
|
+
|
|
6414
|
+
/**
|
|
6415
|
+
* Executes a callback when an element becomes visible.
|
|
6416
|
+
*/
|
|
6417
|
+
function onVisible(element, callback) {
|
|
6418
|
+
if (typeof IntersectionObserver === 'undefined') {
|
|
6419
|
+
return () => {};
|
|
6420
|
+
}
|
|
6421
|
+
const observer = new IntersectionObserver(entries => {
|
|
6422
|
+
entries.forEach(entry => {
|
|
6423
|
+
if (entry.intersectionRatio > 0) {
|
|
6424
|
+
callback();
|
|
6425
|
+
observer.disconnect();
|
|
6426
|
+
}
|
|
6427
|
+
});
|
|
6428
|
+
});
|
|
6429
|
+
observer.observe(element);
|
|
6430
|
+
return () => {
|
|
6431
|
+
observer.disconnect();
|
|
6432
|
+
};
|
|
6433
|
+
}
|
|
6434
|
+
|
|
6435
|
+
let ScrollAreaViewportCssVars = /*#__PURE__*/function (ScrollAreaViewportCssVars) {
|
|
6436
|
+
/**
|
|
6437
|
+
* The distance from the horizontal start edge in pixels.
|
|
6438
|
+
* @type {number}
|
|
6439
|
+
*/
|
|
6440
|
+
ScrollAreaViewportCssVars["scrollAreaOverflowXStart"] = "--scroll-area-overflow-x-start";
|
|
6441
|
+
/**
|
|
6442
|
+
* The distance from the horizontal end edge in pixels.
|
|
6443
|
+
* @type {number}
|
|
6444
|
+
*/
|
|
6445
|
+
ScrollAreaViewportCssVars["scrollAreaOverflowXEnd"] = "--scroll-area-overflow-x-end";
|
|
6446
|
+
/**
|
|
6447
|
+
* The distance from the vertical start edge in pixels.
|
|
6448
|
+
* @type {number}
|
|
6449
|
+
*/
|
|
6450
|
+
ScrollAreaViewportCssVars["scrollAreaOverflowYStart"] = "--scroll-area-overflow-y-start";
|
|
6451
|
+
/**
|
|
6452
|
+
* The distance from the vertical end edge in pixels.
|
|
6453
|
+
* @type {number}
|
|
6454
|
+
*/
|
|
6455
|
+
ScrollAreaViewportCssVars["scrollAreaOverflowYEnd"] = "--scroll-area-overflow-y-end";
|
|
6456
|
+
return ScrollAreaViewportCssVars;
|
|
6457
|
+
}({});
|
|
6458
|
+
|
|
6459
|
+
const SCROLL_EDGE_TOLERANCE_PX = 1;
|
|
6460
|
+
function normalizeScrollOffset(value, max) {
|
|
6461
|
+
if (max <= 0) {
|
|
6462
|
+
return 0;
|
|
6463
|
+
}
|
|
6464
|
+
const clamped = useValueChanged.clamp(value, 0, max);
|
|
6465
|
+
const startDistance = clamped;
|
|
6466
|
+
const endDistance = max - clamped;
|
|
6467
|
+
const withinStartTolerance = startDistance <= SCROLL_EDGE_TOLERANCE_PX;
|
|
6468
|
+
const withinEndTolerance = endDistance <= SCROLL_EDGE_TOLERANCE_PX;
|
|
6469
|
+
if (withinStartTolerance && withinEndTolerance) {
|
|
6470
|
+
return startDistance <= endDistance ? 0 : max;
|
|
6471
|
+
}
|
|
6472
|
+
if (withinStartTolerance) {
|
|
6473
|
+
return 0;
|
|
6474
|
+
}
|
|
6475
|
+
if (withinEndTolerance) {
|
|
6476
|
+
return max;
|
|
6477
|
+
}
|
|
6478
|
+
return clamped;
|
|
6479
|
+
}
|
|
6480
|
+
|
|
6481
|
+
let scrollAreaOverflowVarsRegistered = false;
|
|
6482
|
+
const HAS_RESIZE_OBSERVER = typeof ResizeObserver !== 'undefined';
|
|
6483
|
+
|
|
6484
|
+
/**
|
|
6485
|
+
* Removes inheritance of the scroll area overflow CSS variables, which
|
|
6486
|
+
* improves rendering performance in complex scroll areas with deep subtrees.
|
|
6487
|
+
* Instead, each child must manually opt-in to using these properties by
|
|
6488
|
+
* specifying `inherit`.
|
|
6489
|
+
* See https://motion.dev/blog/web-animation-performance-tier-list
|
|
6490
|
+
* under the "Improving CSS variable performance" section.
|
|
6491
|
+
*/
|
|
6492
|
+
function removeCSSVariableInheritance() {
|
|
6493
|
+
if (scrollAreaOverflowVarsRegistered ||
|
|
6494
|
+
// When `inherits: false`, specifying `inherit` on child elements doesn't work
|
|
6495
|
+
// in Safari. To let CSS features work correctly, this optimization must be skipped.
|
|
6496
|
+
useValueChanged.isWebKit) {
|
|
6497
|
+
return;
|
|
6498
|
+
}
|
|
6499
|
+
if (typeof CSS !== 'undefined' && 'registerProperty' in CSS) {
|
|
6500
|
+
[ScrollAreaViewportCssVars.scrollAreaOverflowXStart, ScrollAreaViewportCssVars.scrollAreaOverflowXEnd, ScrollAreaViewportCssVars.scrollAreaOverflowYStart, ScrollAreaViewportCssVars.scrollAreaOverflowYEnd].forEach(name => {
|
|
6501
|
+
try {
|
|
6502
|
+
CSS.registerProperty({
|
|
6503
|
+
name,
|
|
6504
|
+
syntax: '<length>',
|
|
6505
|
+
inherits: false,
|
|
6506
|
+
initialValue: '0px'
|
|
6507
|
+
});
|
|
6508
|
+
} catch {
|
|
6509
|
+
/* ignore already-registered */
|
|
6510
|
+
}
|
|
6511
|
+
});
|
|
6512
|
+
}
|
|
6513
|
+
scrollAreaOverflowVarsRegistered = true;
|
|
6514
|
+
}
|
|
6515
|
+
|
|
6516
|
+
/**
|
|
6517
|
+
* The actual scrollable container of the scroll area.
|
|
6518
|
+
* Renders a `<div>` element.
|
|
6519
|
+
*
|
|
6520
|
+
* Documentation: [Base UI Scroll Area](https://base-ui.com/react/components/scroll-area)
|
|
6521
|
+
*/
|
|
6522
|
+
const ScrollAreaViewport = /*#__PURE__*/React__namespace.forwardRef(function ScrollAreaViewport(componentProps, forwardedRef) {
|
|
6523
|
+
const {
|
|
6524
|
+
render,
|
|
6525
|
+
className,
|
|
6526
|
+
...elementProps
|
|
6527
|
+
} = componentProps;
|
|
6528
|
+
const {
|
|
6529
|
+
viewportRef,
|
|
6530
|
+
scrollbarYRef,
|
|
6531
|
+
scrollbarXRef,
|
|
6532
|
+
thumbYRef,
|
|
6533
|
+
thumbXRef,
|
|
6534
|
+
cornerRef,
|
|
6535
|
+
cornerSize,
|
|
6536
|
+
setCornerSize,
|
|
6537
|
+
setThumbSize,
|
|
6538
|
+
rootId,
|
|
6539
|
+
setHiddenState,
|
|
6540
|
+
hiddenState,
|
|
6541
|
+
setHasMeasuredScrollbar,
|
|
6542
|
+
handleScroll,
|
|
6543
|
+
setHovering,
|
|
6544
|
+
setOverflowEdges,
|
|
6545
|
+
overflowEdges,
|
|
6546
|
+
overflowEdgeThreshold,
|
|
6547
|
+
scrollingX,
|
|
6548
|
+
scrollingY
|
|
6549
|
+
} = useScrollAreaRootContext();
|
|
6550
|
+
const direction = useDirection();
|
|
6551
|
+
const programmaticScrollRef = React__namespace.useRef(true);
|
|
6552
|
+
const lastMeasuredViewportMetricsRef = React__namespace.useRef([NaN, NaN, NaN, NaN]);
|
|
6553
|
+
const scrollEndTimeout = useValueChanged.useTimeout();
|
|
6554
|
+
const waitForAnimationsTimeout = useValueChanged.useTimeout();
|
|
6555
|
+
const computeThumbPosition = useValueChanged.useStableCallback(() => {
|
|
6556
|
+
const viewportEl = viewportRef.current;
|
|
6557
|
+
const scrollbarYEl = scrollbarYRef.current;
|
|
6558
|
+
const scrollbarXEl = scrollbarXRef.current;
|
|
6559
|
+
const thumbYEl = thumbYRef.current;
|
|
6560
|
+
const thumbXEl = thumbXRef.current;
|
|
6561
|
+
const cornerEl = cornerRef.current;
|
|
6562
|
+
if (!viewportEl) {
|
|
6563
|
+
return;
|
|
6564
|
+
}
|
|
6565
|
+
const scrollableContentHeight = viewportEl.scrollHeight;
|
|
6566
|
+
const scrollableContentWidth = viewportEl.scrollWidth;
|
|
6567
|
+
const viewportHeight = viewportEl.clientHeight;
|
|
6568
|
+
const viewportWidth = viewportEl.clientWidth;
|
|
6569
|
+
const scrollTop = viewportEl.scrollTop;
|
|
6570
|
+
const scrollLeft = viewportEl.scrollLeft;
|
|
6571
|
+
const lastMeasuredViewportMetrics = lastMeasuredViewportMetricsRef.current;
|
|
6572
|
+
const isFirstMeasurement = Number.isNaN(lastMeasuredViewportMetrics[0]);
|
|
6573
|
+
lastMeasuredViewportMetrics[0] = viewportHeight;
|
|
6574
|
+
lastMeasuredViewportMetrics[1] = scrollableContentHeight;
|
|
6575
|
+
lastMeasuredViewportMetrics[2] = viewportWidth;
|
|
6576
|
+
lastMeasuredViewportMetrics[3] = scrollableContentWidth;
|
|
6577
|
+
if (isFirstMeasurement) {
|
|
6578
|
+
setHasMeasuredScrollbar(true);
|
|
6579
|
+
}
|
|
6580
|
+
if (scrollableContentHeight === 0 || scrollableContentWidth === 0) {
|
|
6581
|
+
return;
|
|
6582
|
+
}
|
|
6583
|
+
const nextHiddenState = getHiddenState(viewportEl);
|
|
6584
|
+
const scrollbarYHidden = nextHiddenState.y;
|
|
6585
|
+
const scrollbarXHidden = nextHiddenState.x;
|
|
6586
|
+
const ratioX = viewportWidth / scrollableContentWidth;
|
|
6587
|
+
const ratioY = viewportHeight / scrollableContentHeight;
|
|
6588
|
+
const maxScrollLeft = Math.max(0, scrollableContentWidth - viewportWidth);
|
|
6589
|
+
const maxScrollTop = Math.max(0, scrollableContentHeight - viewportHeight);
|
|
6590
|
+
let scrollLeftFromStart = 0;
|
|
6591
|
+
let scrollLeftFromEnd = 0;
|
|
6592
|
+
if (!scrollbarXHidden) {
|
|
6593
|
+
let rawScrollLeftFromStart = 0;
|
|
6594
|
+
if (direction === 'rtl') {
|
|
6595
|
+
rawScrollLeftFromStart = useValueChanged.clamp(-scrollLeft, 0, maxScrollLeft);
|
|
6596
|
+
} else {
|
|
6597
|
+
rawScrollLeftFromStart = useValueChanged.clamp(scrollLeft, 0, maxScrollLeft);
|
|
6598
|
+
}
|
|
6599
|
+
scrollLeftFromStart = normalizeScrollOffset(rawScrollLeftFromStart, maxScrollLeft);
|
|
6600
|
+
scrollLeftFromEnd = maxScrollLeft - scrollLeftFromStart;
|
|
6601
|
+
}
|
|
6602
|
+
const rawScrollTopFromStart = !scrollbarYHidden ? useValueChanged.clamp(scrollTop, 0, maxScrollTop) : 0;
|
|
6603
|
+
const scrollTopFromStart = !scrollbarYHidden ? normalizeScrollOffset(rawScrollTopFromStart, maxScrollTop) : 0;
|
|
6604
|
+
const scrollTopFromEnd = !scrollbarYHidden ? maxScrollTop - scrollTopFromStart : 0;
|
|
6605
|
+
const nextWidth = scrollbarXHidden ? 0 : viewportWidth;
|
|
6606
|
+
const nextHeight = scrollbarYHidden ? 0 : viewportHeight;
|
|
6607
|
+
let nextCornerWidth = 0;
|
|
6608
|
+
let nextCornerHeight = 0;
|
|
6609
|
+
if (!scrollbarXHidden && !scrollbarYHidden) {
|
|
6610
|
+
nextCornerWidth = scrollbarYEl?.offsetWidth || 0;
|
|
6611
|
+
nextCornerHeight = scrollbarXEl?.offsetHeight || 0;
|
|
6612
|
+
}
|
|
6613
|
+
|
|
6614
|
+
// Only subtract corner size from scrollbar dimensions if the corner hasn't been sized yet.
|
|
6615
|
+
// Once sized, the layout will already account for it.
|
|
6616
|
+
const cornerNotYetSized = cornerSize.width === 0 && cornerSize.height === 0;
|
|
6617
|
+
const cornerWidthOffset = cornerNotYetSized ? nextCornerWidth : 0;
|
|
6618
|
+
const cornerHeightOffset = cornerNotYetSized ? nextCornerHeight : 0;
|
|
6619
|
+
const scrollbarXOffset = getOffset(scrollbarXEl, 'padding', 'x');
|
|
6620
|
+
const scrollbarYOffset = getOffset(scrollbarYEl, 'padding', 'y');
|
|
6621
|
+
const thumbXOffset = getOffset(thumbXEl, 'margin', 'x');
|
|
6622
|
+
const thumbYOffset = getOffset(thumbYEl, 'margin', 'y');
|
|
6623
|
+
const idealNextWidth = nextWidth - scrollbarXOffset - thumbXOffset;
|
|
6624
|
+
const idealNextHeight = nextHeight - scrollbarYOffset - thumbYOffset;
|
|
6625
|
+
const maxNextWidth = scrollbarXEl ? Math.min(scrollbarXEl.offsetWidth - cornerWidthOffset, idealNextWidth) : idealNextWidth;
|
|
6626
|
+
const maxNextHeight = scrollbarYEl ? Math.min(scrollbarYEl.offsetHeight - cornerHeightOffset, idealNextHeight) : idealNextHeight;
|
|
6627
|
+
const clampedNextWidth = Math.max(MIN_THUMB_SIZE, maxNextWidth * ratioX);
|
|
6628
|
+
const clampedNextHeight = Math.max(MIN_THUMB_SIZE, maxNextHeight * ratioY);
|
|
6629
|
+
setThumbSize(prevSize => {
|
|
6630
|
+
if (prevSize.height === clampedNextHeight && prevSize.width === clampedNextWidth) {
|
|
6631
|
+
return prevSize;
|
|
6632
|
+
}
|
|
6633
|
+
return {
|
|
6634
|
+
width: clampedNextWidth,
|
|
6635
|
+
height: clampedNextHeight
|
|
6636
|
+
};
|
|
6637
|
+
});
|
|
6638
|
+
|
|
6639
|
+
// Handle Y (vertical) scroll
|
|
6640
|
+
if (scrollbarYEl && thumbYEl) {
|
|
6641
|
+
const maxThumbOffsetY = scrollbarYEl.offsetHeight - clampedNextHeight - scrollbarYOffset - thumbYOffset;
|
|
6642
|
+
const scrollRangeY = scrollableContentHeight - viewportHeight;
|
|
6643
|
+
const scrollRatioY = scrollRangeY === 0 ? 0 : scrollTop / scrollRangeY;
|
|
6644
|
+
|
|
6645
|
+
// In Safari, don't allow it to go negative or too far as `scrollTop` considers the rubber
|
|
6646
|
+
// band effect.
|
|
6647
|
+
const thumbOffsetY = Math.min(maxThumbOffsetY, Math.max(0, scrollRatioY * maxThumbOffsetY));
|
|
6648
|
+
thumbYEl.style.transform = `translate3d(0,${thumbOffsetY}px,0)`;
|
|
6649
|
+
}
|
|
6650
|
+
|
|
6651
|
+
// Handle X (horizontal) scroll
|
|
6652
|
+
if (scrollbarXEl && thumbXEl) {
|
|
6653
|
+
const maxThumbOffsetX = scrollbarXEl.offsetWidth - clampedNextWidth - scrollbarXOffset - thumbXOffset;
|
|
6654
|
+
const scrollRangeX = scrollableContentWidth - viewportWidth;
|
|
6655
|
+
const scrollRatioX = scrollRangeX === 0 ? 0 : scrollLeft / scrollRangeX;
|
|
6656
|
+
|
|
6657
|
+
// In Safari, don't allow it to go negative or too far as `scrollLeft` considers the rubber
|
|
6658
|
+
// band effect.
|
|
6659
|
+
const thumbOffsetX = direction === 'rtl' ? useValueChanged.clamp(scrollRatioX * maxThumbOffsetX, -maxThumbOffsetX, 0) : useValueChanged.clamp(scrollRatioX * maxThumbOffsetX, 0, maxThumbOffsetX);
|
|
6660
|
+
thumbXEl.style.transform = `translate3d(${thumbOffsetX}px,0,0)`;
|
|
6661
|
+
}
|
|
6662
|
+
const overflowMetricsPx = [[ScrollAreaViewportCssVars.scrollAreaOverflowXStart, scrollLeftFromStart], [ScrollAreaViewportCssVars.scrollAreaOverflowXEnd, scrollLeftFromEnd], [ScrollAreaViewportCssVars.scrollAreaOverflowYStart, scrollTopFromStart], [ScrollAreaViewportCssVars.scrollAreaOverflowYEnd, scrollTopFromEnd]];
|
|
6663
|
+
for (const [cssVar, value] of overflowMetricsPx) {
|
|
6664
|
+
viewportEl.style.setProperty(cssVar, `${value}px`);
|
|
6665
|
+
}
|
|
6666
|
+
if (cornerEl) {
|
|
6667
|
+
if (scrollbarXHidden || scrollbarYHidden) {
|
|
6668
|
+
setCornerSize({
|
|
6669
|
+
width: 0,
|
|
6670
|
+
height: 0
|
|
6671
|
+
});
|
|
6672
|
+
} else if (!scrollbarXHidden && !scrollbarYHidden) {
|
|
6673
|
+
setCornerSize({
|
|
6674
|
+
width: nextCornerWidth,
|
|
6675
|
+
height: nextCornerHeight
|
|
6676
|
+
});
|
|
6677
|
+
}
|
|
6678
|
+
}
|
|
6679
|
+
setHiddenState(prevState => mergeHiddenState(prevState, nextHiddenState));
|
|
6680
|
+
const nextOverflowEdges = {
|
|
6681
|
+
xStart: !scrollbarXHidden && scrollLeftFromStart > overflowEdgeThreshold.xStart,
|
|
6682
|
+
xEnd: !scrollbarXHidden && scrollLeftFromEnd > overflowEdgeThreshold.xEnd,
|
|
6683
|
+
yStart: !scrollbarYHidden && scrollTopFromStart > overflowEdgeThreshold.yStart,
|
|
6684
|
+
yEnd: !scrollbarYHidden && scrollTopFromEnd > overflowEdgeThreshold.yEnd
|
|
6685
|
+
};
|
|
6686
|
+
setOverflowEdges(prev => {
|
|
6687
|
+
if (prev.xStart === nextOverflowEdges.xStart && prev.xEnd === nextOverflowEdges.xEnd && prev.yStart === nextOverflowEdges.yStart && prev.yEnd === nextOverflowEdges.yEnd) {
|
|
6688
|
+
return prev;
|
|
6689
|
+
}
|
|
6690
|
+
return nextOverflowEdges;
|
|
6691
|
+
});
|
|
6692
|
+
});
|
|
6693
|
+
useValueChanged.useIsoLayoutEffect(() => {
|
|
6694
|
+
if (!viewportRef.current) {
|
|
6695
|
+
return undefined;
|
|
6696
|
+
}
|
|
6697
|
+
removeCSSVariableInheritance();
|
|
6698
|
+
if (HAS_RESIZE_OBSERVER) {
|
|
6699
|
+
return undefined;
|
|
6700
|
+
}
|
|
6701
|
+
return onVisible(viewportRef.current, () => {
|
|
6702
|
+
computeThumbPosition();
|
|
6703
|
+
});
|
|
6704
|
+
}, [computeThumbPosition, viewportRef]);
|
|
6705
|
+
useValueChanged.useIsoLayoutEffect(() => {
|
|
6706
|
+
// Wait for scrollbar and thumb refs after hidden-state toggles, and refresh math on direction flips.
|
|
6707
|
+
queueMicrotask(computeThumbPosition);
|
|
6708
|
+
}, [computeThumbPosition, hiddenState, direction]);
|
|
6709
|
+
useValueChanged.useIsoLayoutEffect(() => {
|
|
6710
|
+
// `onMouseEnter` doesn't fire upon load, so we need to check if the viewport is already
|
|
6711
|
+
// being hovered.
|
|
6712
|
+
if (viewportRef.current?.matches(':hover')) {
|
|
6713
|
+
setHovering(true);
|
|
6714
|
+
}
|
|
6715
|
+
}, [viewportRef, setHovering]);
|
|
6716
|
+
React__namespace.useEffect(() => {
|
|
6717
|
+
const viewport = viewportRef.current;
|
|
6718
|
+
if (!HAS_RESIZE_OBSERVER || !viewport) {
|
|
6719
|
+
return undefined;
|
|
6720
|
+
}
|
|
6721
|
+
let hasInitialized = false;
|
|
6722
|
+
const ro = new ResizeObserver(() => {
|
|
6723
|
+
// Avoid duplicate mount-time recompute when observer data matches what the mount
|
|
6724
|
+
// scheduling pass already measured. If dimensions changed before the first observer
|
|
6725
|
+
// delivery, keep the recompute so overflow transitions stay in sync.
|
|
6726
|
+
if (!hasInitialized) {
|
|
6727
|
+
hasInitialized = true;
|
|
6728
|
+
const lastMeasuredViewportMetrics = lastMeasuredViewportMetricsRef.current;
|
|
6729
|
+
if (lastMeasuredViewportMetrics[0] === viewport.clientHeight && lastMeasuredViewportMetrics[1] === viewport.scrollHeight && lastMeasuredViewportMetrics[2] === viewport.clientWidth && lastMeasuredViewportMetrics[3] === viewport.scrollWidth) {
|
|
6730
|
+
return;
|
|
6731
|
+
}
|
|
6732
|
+
}
|
|
6733
|
+
computeThumbPosition();
|
|
6734
|
+
});
|
|
6735
|
+
ro.observe(viewport);
|
|
6736
|
+
|
|
6737
|
+
// If there are animations in the viewport, wait for them to finish and then recompute the thumb position.
|
|
6738
|
+
// This is necessary when the viewport contains a Dialog that is animating its popup on open
|
|
6739
|
+
// and the popup is using a transform for the animation, which affects the size of the viewport.
|
|
6740
|
+
// Without this, the thumb position will be incorrect until scrolling (i.e. if the scrollbar shows
|
|
6741
|
+
// on hover, the thumb has an incorrect size).
|
|
6742
|
+
// We assume the user is using `onOpenChangeComplete` to hide the scrollbar
|
|
6743
|
+
// until animations complete because otherwise the scrollbar would show the thumb resizing mid-animation.
|
|
6744
|
+
waitForAnimationsTimeout.start(0, () => {
|
|
6745
|
+
const animations = viewport.getAnimations({
|
|
6746
|
+
subtree: true
|
|
6747
|
+
});
|
|
6748
|
+
if (animations.length === 0) {
|
|
6749
|
+
return;
|
|
6750
|
+
}
|
|
6751
|
+
Promise.allSettled(animations.map(animation => animation.finished)).then(computeThumbPosition).catch(() => {});
|
|
6752
|
+
});
|
|
6753
|
+
return () => {
|
|
6754
|
+
ro.disconnect();
|
|
6755
|
+
waitForAnimationsTimeout.clear();
|
|
6756
|
+
};
|
|
6757
|
+
}, [computeThumbPosition, viewportRef, waitForAnimationsTimeout]);
|
|
6758
|
+
function handleUserInteraction() {
|
|
6759
|
+
programmaticScrollRef.current = false;
|
|
6760
|
+
}
|
|
6761
|
+
const props = {
|
|
6762
|
+
role: 'presentation',
|
|
6763
|
+
...(rootId && {
|
|
6764
|
+
'data-id': `${rootId}-viewport`
|
|
6765
|
+
}),
|
|
6766
|
+
// https://accessibilityinsights.io/info-examples/web/scrollable-region-focusable/
|
|
6767
|
+
// Keep non-scrollable viewports out of tab order.
|
|
6768
|
+
tabIndex: hiddenState.x && hiddenState.y ? -1 : 0,
|
|
6769
|
+
className: styleDisableScrollbar.className,
|
|
6770
|
+
style: {
|
|
6771
|
+
overflow: 'scroll'
|
|
6772
|
+
},
|
|
6773
|
+
onScroll() {
|
|
6774
|
+
if (!viewportRef.current) {
|
|
6775
|
+
return;
|
|
6776
|
+
}
|
|
6777
|
+
computeThumbPosition();
|
|
6778
|
+
if (!programmaticScrollRef.current) {
|
|
6779
|
+
handleScroll({
|
|
6780
|
+
x: viewportRef.current.scrollLeft,
|
|
6781
|
+
y: viewportRef.current.scrollTop
|
|
6782
|
+
});
|
|
6783
|
+
}
|
|
6784
|
+
|
|
6785
|
+
// Debounce the restoration of the programmatic flag so that it only
|
|
6786
|
+
// flips back to `true` once scrolling has come to a rest. This ensures
|
|
6787
|
+
// that momentum scrolling (where no further user-interaction events fire)
|
|
6788
|
+
// is still treated as user-driven.
|
|
6789
|
+
// 100 ms without scroll events ≈ scroll end
|
|
6790
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollend_event
|
|
6791
|
+
scrollEndTimeout.start(100, () => {
|
|
6792
|
+
programmaticScrollRef.current = true;
|
|
6793
|
+
});
|
|
6794
|
+
},
|
|
6795
|
+
onWheel: handleUserInteraction,
|
|
6796
|
+
onTouchMove: handleUserInteraction,
|
|
6797
|
+
onPointerMove: handleUserInteraction,
|
|
6798
|
+
onPointerEnter: handleUserInteraction,
|
|
6799
|
+
onKeyDown: handleUserInteraction
|
|
6800
|
+
};
|
|
6801
|
+
const viewportState = React__namespace.useMemo(() => ({
|
|
6802
|
+
scrolling: scrollingX || scrollingY,
|
|
6803
|
+
hasOverflowX: !hiddenState.x,
|
|
6804
|
+
hasOverflowY: !hiddenState.y,
|
|
6805
|
+
overflowXStart: overflowEdges.xStart,
|
|
6806
|
+
overflowXEnd: overflowEdges.xEnd,
|
|
6807
|
+
overflowYStart: overflowEdges.yStart,
|
|
6808
|
+
overflowYEnd: overflowEdges.yEnd,
|
|
6809
|
+
cornerHidden: hiddenState.corner
|
|
6810
|
+
}), [scrollingX, scrollingY, hiddenState.x, hiddenState.y, hiddenState.corner, overflowEdges]);
|
|
6811
|
+
const element = useRenderElement.useRenderElement('div', componentProps, {
|
|
6812
|
+
ref: [forwardedRef, viewportRef],
|
|
6813
|
+
state: viewportState,
|
|
6814
|
+
props: [props, elementProps],
|
|
6815
|
+
stateAttributesMapping: scrollAreaStateAttributesMapping
|
|
6816
|
+
});
|
|
6817
|
+
const contextValue = React__namespace.useMemo(() => ({
|
|
6818
|
+
computeThumbPosition
|
|
6819
|
+
}), [computeThumbPosition]);
|
|
6820
|
+
return /*#__PURE__*/jsxRuntime.jsx(ScrollAreaViewportContext.Provider, {
|
|
6821
|
+
value: contextValue,
|
|
6822
|
+
children: element
|
|
6823
|
+
});
|
|
6824
|
+
});
|
|
6825
|
+
if (process.env.NODE_ENV !== "production") ScrollAreaViewport.displayName = "ScrollAreaViewport";
|
|
6826
|
+
function getHiddenState(viewport) {
|
|
6827
|
+
const y = viewport.clientHeight >= viewport.scrollHeight;
|
|
6828
|
+
const x = viewport.clientWidth >= viewport.scrollWidth;
|
|
6829
|
+
return {
|
|
6830
|
+
y,
|
|
6831
|
+
x,
|
|
6832
|
+
corner: y || x
|
|
6833
|
+
};
|
|
6834
|
+
}
|
|
6835
|
+
function mergeHiddenState(prevState, nextState) {
|
|
6836
|
+
if (prevState.y === nextState.y && prevState.x === nextState.x && prevState.corner === nextState.corner) {
|
|
6837
|
+
return prevState;
|
|
6838
|
+
}
|
|
6839
|
+
return nextState;
|
|
6840
|
+
}
|
|
6841
|
+
|
|
5812
6842
|
exports.ARROW_DOWN = ARROW_DOWN$1;
|
|
5813
6843
|
exports.ARROW_LEFT = ARROW_LEFT$1;
|
|
5814
6844
|
exports.ARROW_RIGHT = ARROW_RIGHT$1;
|
|
5815
6845
|
exports.ARROW_UP = ARROW_UP$1;
|
|
5816
6846
|
exports.BASE_UI_SWIPE_IGNORE_SELECTOR = BASE_UI_SWIPE_IGNORE_SELECTOR;
|
|
5817
|
-
exports.CLICK_TRIGGER_IDENTIFIER = CLICK_TRIGGER_IDENTIFIER;
|
|
5818
6847
|
exports.COMPOSITE_KEYS = COMPOSITE_KEYS;
|
|
5819
6848
|
exports.CommonPopupDataAttributes = CommonPopupDataAttributes;
|
|
5820
6849
|
exports.DISABLED_TRANSITIONS_STYLE = DISABLED_TRANSITIONS_STYLE;
|
|
@@ -5830,6 +6859,7 @@ exports.DrawerPopupDataAttributes = DrawerPopupDataAttributes;
|
|
|
5830
6859
|
exports.DrawerPortal = DrawerPortal;
|
|
5831
6860
|
exports.DrawerProviderContext = DrawerProviderContext;
|
|
5832
6861
|
exports.DrawerRoot = DrawerRoot;
|
|
6862
|
+
exports.DrawerTrigger = DrawerTrigger;
|
|
5833
6863
|
exports.DrawerViewportContext = DrawerViewportContext;
|
|
5834
6864
|
exports.FloatingFocusManager = FloatingFocusManager;
|
|
5835
6865
|
exports.FloatingNode = FloatingNode;
|
|
@@ -5843,6 +6873,9 @@ exports.PATIENT_CLICK_THRESHOLD = PATIENT_CLICK_THRESHOLD;
|
|
|
5843
6873
|
exports.POPUP_COLLISION_AVOIDANCE = POPUP_COLLISION_AVOIDANCE;
|
|
5844
6874
|
exports.PopupTriggerMap = PopupTriggerMap;
|
|
5845
6875
|
exports.ReactStore = ReactStore;
|
|
6876
|
+
exports.ScrollAreaRoot = ScrollAreaRoot;
|
|
6877
|
+
exports.ScrollAreaRootCssVars = ScrollAreaRootCssVars;
|
|
6878
|
+
exports.ScrollAreaViewport = ScrollAreaViewport;
|
|
5846
6879
|
exports.Store = Store;
|
|
5847
6880
|
exports.TYPEABLE_SELECTOR = TYPEABLE_SELECTOR;
|
|
5848
6881
|
exports.TYPEAHEAD_RESET_MS = TYPEAHEAD_RESET_MS;
|
|
@@ -5864,6 +6897,7 @@ exports.getMaxListIndex = getMaxListIndex;
|
|
|
5864
6897
|
exports.getMinListIndex = getMinListIndex;
|
|
5865
6898
|
exports.getNextTabbable = getNextTabbable;
|
|
5866
6899
|
exports.getNodeChildren = getNodeChildren;
|
|
6900
|
+
exports.getOffset = getOffset;
|
|
5867
6901
|
exports.getTabbableAfterElement = getTabbableAfterElement;
|
|
5868
6902
|
exports.getTabbableBeforeElement = getTabbableBeforeElement;
|
|
5869
6903
|
exports.getTarget = getTarget;
|
|
@@ -5879,9 +6913,12 @@ exports.matchesFocusVisible = matchesFocusVisible;
|
|
|
5879
6913
|
exports.popupStateMapping = popupStateMapping;
|
|
5880
6914
|
exports.popupStoreSelectors = popupStoreSelectors;
|
|
5881
6915
|
exports.pressableTriggerOpenStateMapping = pressableTriggerOpenStateMapping;
|
|
6916
|
+
exports.scrollAreaStateAttributesMapping = scrollAreaStateAttributesMapping;
|
|
5882
6917
|
exports.triggerOpenStateMapping = triggerOpenStateMapping;
|
|
6918
|
+
exports.useClick = useClick;
|
|
5883
6919
|
exports.useDialogPortalContext = useDialogPortalContext;
|
|
5884
6920
|
exports.useDialogRootContext = useDialogRootContext;
|
|
6921
|
+
exports.useDirection = useDirection;
|
|
5885
6922
|
exports.useDismiss = useDismiss;
|
|
5886
6923
|
exports.useDrawerProviderContext = useDrawerProviderContext;
|
|
5887
6924
|
exports.useDrawerRootContext = useDrawerRootContext;
|
|
@@ -5895,6 +6932,8 @@ exports.useOnFirstRender = useOnFirstRender;
|
|
|
5895
6932
|
exports.useOpenInteractionType = useOpenInteractionType;
|
|
5896
6933
|
exports.useOpenStateTransitions = useOpenStateTransitions;
|
|
5897
6934
|
exports.useRole = useRole;
|
|
6935
|
+
exports.useScrollAreaRootContext = useScrollAreaRootContext;
|
|
6936
|
+
exports.useScrollAreaViewportContext = useScrollAreaViewportContext;
|
|
5898
6937
|
exports.useScrollLock = useScrollLock;
|
|
5899
6938
|
exports.useStore = useStore;
|
|
5900
6939
|
exports.useSyncedFloatingRootContext = useSyncedFloatingRootContext;
|