@yahoo/uds 3.114.0-beta.3 → 3.115.0-beta.1
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/dist/automated-config/dist/generated/autoVariants.cjs +3 -0
- package/dist/automated-config/dist/generated/autoVariants.d.cts +3 -0
- package/dist/automated-config/dist/generated/autoVariants.d.ts +3 -0
- package/dist/automated-config/dist/generated/autoVariants.js +3 -0
- package/dist/automated-config/dist/generated/generatedConfigs.cjs +1883 -0
- package/dist/automated-config/dist/generated/generatedConfigs.d.cts +175 -1
- package/dist/automated-config/dist/generated/generatedConfigs.d.ts +175 -1
- package/dist/automated-config/dist/generated/generatedConfigs.js +1882 -1
- package/dist/automated-config/dist/generated/universalTokensConfigAuto.cjs +84 -0
- package/dist/automated-config/dist/generated/universalTokensConfigAuto.d.cts +3 -1
- package/dist/automated-config/dist/generated/universalTokensConfigAuto.d.ts +3 -1
- package/dist/automated-config/dist/generated/universalTokensConfigAuto.js +84 -0
- package/dist/automated-config/dist/properties.cjs +57 -11
- package/dist/automated-config/dist/properties.d.cts +8 -0
- package/dist/automated-config/dist/properties.d.ts +8 -0
- package/dist/automated-config/dist/properties.js +57 -11
- package/dist/automated-config/dist/utils/getConfigVariantProperties.d.cts +2 -2
- package/dist/automated-config/dist/utils/getConfigVariantProperties.d.ts +2 -2
- package/dist/cli/commands/sync.cjs +4 -0
- package/dist/cli/commands/sync.js +4 -0
- package/dist/components/Scrim.cjs +28 -0
- package/dist/components/Scrim.d.cts +14 -0
- package/dist/components/Scrim.d.ts +14 -0
- package/dist/components/Scrim.js +26 -0
- package/dist/components/client/BottomSheet/BottomSheet.cjs +209 -0
- package/dist/components/client/BottomSheet/BottomSheet.d.cts +77 -0
- package/dist/components/client/BottomSheet/BottomSheet.d.ts +77 -0
- package/dist/components/client/BottomSheet/BottomSheet.js +207 -0
- package/dist/components/client/BottomSheet/BottomSheetContent.cjs +26 -0
- package/dist/components/client/BottomSheet/BottomSheetContent.d.cts +15 -0
- package/dist/components/client/BottomSheet/BottomSheetContent.d.ts +15 -0
- package/dist/components/client/BottomSheet/BottomSheetContent.js +24 -0
- package/dist/components/client/BottomSheet/BottomSheetDismiss.cjs +15 -0
- package/dist/components/client/BottomSheet/BottomSheetDismiss.d.cts +12 -0
- package/dist/components/client/BottomSheet/BottomSheetDismiss.d.ts +12 -0
- package/dist/components/client/BottomSheet/BottomSheetDismiss.js +13 -0
- package/dist/components/client/BottomSheet/BottomSheetHandle.cjs +30 -0
- package/dist/components/client/BottomSheet/BottomSheetHandle.d.cts +19 -0
- package/dist/components/client/BottomSheet/BottomSheetHandle.d.ts +19 -0
- package/dist/components/client/BottomSheet/BottomSheetHandle.js +28 -0
- package/dist/components/client/BottomSheet/BottomSheetHeader.cjs +42 -0
- package/dist/components/client/BottomSheet/BottomSheetHeader.d.cts +18 -0
- package/dist/components/client/BottomSheet/BottomSheetHeader.d.ts +18 -0
- package/dist/components/client/BottomSheet/BottomSheetHeader.js +40 -0
- package/dist/components/client/BottomSheet/BottomSheetProvider.cjs +21 -0
- package/dist/components/client/BottomSheet/BottomSheetProvider.d.cts +19 -0
- package/dist/components/client/BottomSheet/BottomSheetProvider.d.ts +19 -0
- package/dist/components/client/BottomSheet/BottomSheetProvider.js +19 -0
- package/dist/components/client/BottomSheet/BottomSheetTrigger.cjs +15 -0
- package/dist/components/client/BottomSheet/BottomSheetTrigger.d.cts +12 -0
- package/dist/components/client/BottomSheet/BottomSheetTrigger.d.ts +12 -0
- package/dist/components/client/BottomSheet/BottomSheetTrigger.js +13 -0
- package/dist/components/client/BottomSheet/UDSBottomSheetConfigProvider.cjs +32 -0
- package/dist/components/client/BottomSheet/UDSBottomSheetConfigProvider.d.cts +22 -0
- package/dist/components/client/BottomSheet/UDSBottomSheetConfigProvider.d.ts +22 -0
- package/dist/components/client/BottomSheet/UDSBottomSheetConfigProvider.js +29 -0
- package/dist/components/client/BottomSheet/index.cjs +22 -0
- package/dist/components/client/BottomSheet/index.d.cts +10 -0
- package/dist/components/client/BottomSheet/index.d.ts +10 -0
- package/dist/components/client/BottomSheet/index.js +12 -0
- package/dist/components/client/BottomSheet/useBottomSheetDrag.cjs +188 -0
- package/dist/components/client/BottomSheet/useBottomSheetDrag.d.cts +44 -0
- package/dist/components/client/BottomSheet/useBottomSheetDrag.d.ts +44 -0
- package/dist/components/client/BottomSheet/useBottomSheetDrag.js +185 -0
- package/dist/components/client/BottomSheet/useBottomSheetSnapModel.cjs +138 -0
- package/dist/components/client/BottomSheet/useBottomSheetSnapModel.d.cts +46 -0
- package/dist/components/client/BottomSheet/useBottomSheetSnapModel.d.ts +46 -0
- package/dist/components/client/BottomSheet/useBottomSheetSnapModel.js +135 -0
- package/dist/components/client/BottomSheet/useBottomSheetStore.cjs +34 -0
- package/dist/components/client/BottomSheet/useBottomSheetStore.d.cts +38 -0
- package/dist/components/client/BottomSheet/useBottomSheetStore.d.ts +38 -0
- package/dist/components/client/BottomSheet/useBottomSheetStore.js +31 -0
- package/dist/components/client/BottomSheet/useBottomSheetStoreInternal.cjs +17 -0
- package/dist/components/client/BottomSheet/useBottomSheetStoreInternal.d.cts +13 -0
- package/dist/components/client/BottomSheet/useBottomSheetStoreInternal.d.ts +13 -0
- package/dist/components/client/BottomSheet/useBottomSheetStoreInternal.js +15 -0
- package/dist/components/client/BottomSheet/useExpansionMargins.cjs +89 -0
- package/dist/components/client/BottomSheet/useExpansionMargins.d.cts +34 -0
- package/dist/components/client/BottomSheet/useExpansionMargins.d.ts +34 -0
- package/dist/components/client/BottomSheet/useExpansionMargins.js +87 -0
- package/dist/components/client/BottomSheet/useViewportHeight.cjs +32 -0
- package/dist/components/client/BottomSheet/useViewportHeight.d.cts +9 -0
- package/dist/components/client/BottomSheet/useViewportHeight.d.ts +9 -0
- package/dist/components/client/BottomSheet/useViewportHeight.js +30 -0
- package/dist/components/client/BottomSheet/useVirtualKeyboard.cjs +48 -0
- package/dist/components/client/BottomSheet/useVirtualKeyboard.d.cts +10 -0
- package/dist/components/client/BottomSheet/useVirtualKeyboard.d.ts +10 -0
- package/dist/components/client/BottomSheet/useVirtualKeyboard.js +46 -0
- package/dist/components/client/BottomSheet/utils.cjs +128 -0
- package/dist/components/client/BottomSheet/utils.d.cts +61 -0
- package/dist/components/client/BottomSheet/utils.d.ts +61 -0
- package/dist/components/client/BottomSheet/utils.js +118 -0
- package/dist/components/client/Menu/Menu.Content.cjs +1 -1
- package/dist/components/client/Menu/Menu.Content.js +1 -1
- package/dist/components/client/Menu/Menu.ItemCheckbox.d.cts +1 -1
- package/dist/components/client/Menu/Menu.ItemCheckbox.d.ts +1 -1
- package/dist/components/client/Menu/Menu.index.d.cts +1 -1
- package/dist/components/client/index.cjs +16 -0
- package/dist/components/client/index.d.cts +10 -1
- package/dist/components/client/index.d.ts +10 -1
- package/dist/components/client/index.js +9 -1
- package/dist/components/client/providers/UDSConfigProvider.cjs +10 -6
- package/dist/components/client/providers/UDSConfigProvider.d.cts +1 -0
- package/dist/components/client/providers/UDSConfigProvider.d.ts +1 -0
- package/dist/components/client/providers/UDSConfigProvider.js +10 -6
- package/dist/components/index.cjs +24 -0
- package/dist/components/index.d.cts +9 -1
- package/dist/components/index.d.ts +9 -1
- package/dist/components/index.js +17 -1
- package/dist/config/dist/index.cjs +110 -2
- package/dist/config/dist/index.js +110 -2
- package/dist/fixtures/dist/index.cjs +103 -0
- package/dist/fixtures/dist/index.d.cts +3 -2
- package/dist/fixtures/dist/index.d.ts +3 -2
- package/dist/fixtures/dist/index.js +103 -1
- package/dist/fixtures/index.cjs +1 -0
- package/dist/fixtures/index.d.cts +2 -2
- package/dist/fixtures/index.d.ts +2 -2
- package/dist/fixtures/index.js +2 -2
- package/dist/index.cjs +20 -0
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +11 -2
- package/dist/runtime/bottomSheetConfig.cjs +11 -0
- package/dist/runtime/bottomSheetConfig.d.cts +15 -0
- package/dist/runtime/bottomSheetConfig.d.ts +15 -0
- package/dist/runtime/bottomSheetConfig.js +9 -0
- package/dist/runtime/index.cjs +2 -0
- package/dist/runtime/index.d.cts +2 -1
- package/dist/runtime/index.d.ts +2 -1
- package/dist/runtime/index.js +2 -1
- package/dist/runtime/udsConfig.cjs +2 -0
- package/dist/runtime/udsConfig.d.cts +2 -0
- package/dist/runtime/udsConfig.d.ts +2 -0
- package/dist/runtime/udsConfig.js +2 -0
- package/dist/styles/styler.d.cts +47 -44
- package/dist/styles/styler.d.ts +51 -48
- package/dist/styles/variants.d.cts +9 -0
- package/dist/styles/variants.d.ts +9 -0
- package/dist/tailwind/dist/tailwind/plugins/components.cjs +2 -0
- package/dist/tailwind/dist/tailwind/plugins/components.js +3 -1
- package/dist/tailwind/dist/tailwind/utils/getFontStyles.d.cts +1 -1
- package/dist/tailwind/dist/tailwind/utils/getFontStyles.d.ts +1 -1
- package/dist/tailwind/dist/tailwind/utils/getShadowStyles.d.cts +4 -4
- package/dist/tailwind/dist/tailwind/utils/getShadowStyles.d.ts +4 -4
- package/dist/tokens/automation/configs/index.cjs +2 -0
- package/dist/tokens/automation/configs/index.d.cts +2 -2
- package/dist/tokens/automation/configs/index.d.ts +2 -2
- package/dist/tokens/automation/configs/index.js +2 -2
- package/dist/tokens/automation/index.cjs +2 -0
- package/dist/tokens/automation/index.d.cts +2 -2
- package/dist/tokens/automation/index.d.ts +2 -2
- package/dist/tokens/automation/index.js +2 -2
- package/dist/tokens/index.cjs +2 -0
- package/dist/tokens/index.d.cts +3 -3
- package/dist/tokens/index.d.ts +3 -3
- package/dist/tokens/index.js +2 -2
- package/dist/tokens/types.d.cts +2 -2
- package/dist/tokens/types.d.ts +2 -2
- package/dist/types/dist/index.d.cts +76 -1
- package/dist/types/dist/index.d.ts +76 -1
- package/dist/uds/generated/componentData.cjs +358 -117
- package/dist/uds/generated/componentData.js +305 -118
- package/dist/uds/generated/tailwindPurge.cjs +57 -29
- package/dist/uds/generated/tailwindPurge.js +57 -29
- package/generated/componentData.json +475 -209
- package/generated/tailwindPurge.ts +39 -8
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
'use client';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
5
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
6
|
+
const require_styles_styler = require('../styles/styler.cjs');
|
|
7
|
+
const require_components_Box = require('./Box.cjs');
|
|
8
|
+
let react = require("react");
|
|
9
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
|
+
|
|
11
|
+
//#region src/components/Scrim.tsx
|
|
12
|
+
const Scrim = (0, react.forwardRef)(function Scrim({ className, style, variant = "default", position = "fixed", animateOpacity = false, ...props }, ref) {
|
|
13
|
+
const rootVariantClass = require_styles_styler.getStyles({ scrimVariantRoot: variant });
|
|
14
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_Box.Box, {
|
|
15
|
+
ref,
|
|
16
|
+
display: "block",
|
|
17
|
+
className: require_styles_styler.cx(position === "fixed" ? "fixed" : "absolute", "inset-0 z-40", animateOpacity ? "transition-opacity duration-150 data-[enter]:opacity-100 [&:not([data-enter])]:opacity-0" : "opacity-100", "uds-bgBlurFallback", rootVariantClass, className),
|
|
18
|
+
...props,
|
|
19
|
+
style: {
|
|
20
|
+
...style,
|
|
21
|
+
backgroundColor: "rgb(var(--uds-scrim-background-color) / var(--uds-scrim-opacity))"
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
Scrim.displayName = "Scrim";
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
exports.Scrim = Scrim;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
import { DivProps } from "./Box.cjs";
|
|
3
|
+
import * as react from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/components/Scrim.d.ts
|
|
6
|
+
interface ScrimProps extends DivProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
variant?: 'default';
|
|
9
|
+
position?: 'fixed' | 'absolute';
|
|
10
|
+
animateOpacity?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare const Scrim: react.ForwardRefExoticComponent<ScrimProps & react.RefAttributes<HTMLDivElement>>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { Scrim, type ScrimProps };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
import { DivProps } from "./Box.js";
|
|
3
|
+
import * as react from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/components/Scrim.d.ts
|
|
6
|
+
interface ScrimProps extends DivProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
variant?: 'default';
|
|
9
|
+
position?: 'fixed' | 'absolute';
|
|
10
|
+
animateOpacity?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare const Scrim: react.ForwardRefExoticComponent<ScrimProps & react.RefAttributes<HTMLDivElement>>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { Scrim, type ScrimProps };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
'use client';
|
|
3
|
+
|
|
4
|
+
import { cx, getStyles } from "../styles/styler.js";
|
|
5
|
+
import { Box } from "./Box.js";
|
|
6
|
+
import { forwardRef } from "react";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
|
|
9
|
+
//#region src/components/Scrim.tsx
|
|
10
|
+
const Scrim = forwardRef(function Scrim({ className, style, variant = "default", position = "fixed", animateOpacity = false, ...props }, ref) {
|
|
11
|
+
const rootVariantClass = getStyles({ scrimVariantRoot: variant });
|
|
12
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
13
|
+
ref,
|
|
14
|
+
display: "block",
|
|
15
|
+
className: cx(position === "fixed" ? "fixed" : "absolute", "inset-0 z-40", animateOpacity ? "transition-opacity duration-150 data-[enter]:opacity-100 [&:not([data-enter])]:opacity-0" : "opacity-100", "uds-bgBlurFallback", rootVariantClass, className),
|
|
16
|
+
...props,
|
|
17
|
+
style: {
|
|
18
|
+
...style,
|
|
19
|
+
backgroundColor: "rgb(var(--uds-scrim-background-color) / var(--uds-scrim-opacity))"
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
Scrim.displayName = "Scrim";
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { Scrim };
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
|
|
5
|
+
const require_styles_styler = require('../../../styles/styler.cjs');
|
|
6
|
+
const require_components_Box = require('../../Box.cjs');
|
|
7
|
+
const require_components_Scrim = require('../../Scrim.cjs');
|
|
8
|
+
const require_components_client_BottomSheet_BottomSheetHandle = require('./BottomSheetHandle.cjs');
|
|
9
|
+
const require_components_client_BottomSheet_UDSBottomSheetConfigProvider = require('./UDSBottomSheetConfigProvider.cjs');
|
|
10
|
+
const require_components_client_BottomSheet_useBottomSheetDrag = require('./useBottomSheetDrag.cjs');
|
|
11
|
+
const require_components_client_BottomSheet_useBottomSheetSnapModel = require('./useBottomSheetSnapModel.cjs');
|
|
12
|
+
const require_components_client_BottomSheet_useBottomSheetStore = require('./useBottomSheetStore.cjs');
|
|
13
|
+
const require_components_client_BottomSheet_useExpansionMargins = require('./useExpansionMargins.cjs');
|
|
14
|
+
const require_components_client_BottomSheet_useViewportHeight = require('./useViewportHeight.cjs');
|
|
15
|
+
const require_components_client_BottomSheet_useVirtualKeyboard = require('./useVirtualKeyboard.cjs');
|
|
16
|
+
let react = require("react");
|
|
17
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
18
|
+
let _ariakit_react = require("@ariakit/react");
|
|
19
|
+
|
|
20
|
+
//#region src/components/client/BottomSheet/BottomSheet.tsx
|
|
21
|
+
/**
|
|
22
|
+
* Drag-to-dismiss distance threshold as a ratio of the lowest snap point's
|
|
23
|
+
* visible height. Dragging down past this fraction of the height dismisses
|
|
24
|
+
* the sheet (regardless of velocity).
|
|
25
|
+
*
|
|
26
|
+
* Velocity and distance are OR conditions — exceeding either one triggers dismissal.
|
|
27
|
+
*/
|
|
28
|
+
const DRAG_DISMISS_THRESHOLD_RATIO = .25;
|
|
29
|
+
/**
|
|
30
|
+
* Top inset reserved when calculating max sheet height.
|
|
31
|
+
* Keeps a visible sliver of page content so the fully expanded state still reads as a bottom sheet.
|
|
32
|
+
*/
|
|
33
|
+
const SHEET_MAX_HEIGHT_TOP_OFFSET_PX = 26;
|
|
34
|
+
function BottomSheet({ children, className: sheetClassName, controller: controllerProp, variant = "default", snapPoints: snapPointsProp, defaultSnapPointIndex = 0, snapPointIndex: snapPointIndexProp, onSnapPointChange, height, modal = true, portal = true, portalElement, dismissible = true, enableDrag = true, showHandleIndicator = true, hideOnEscape = true, onClose, backdrop, preventBodyScroll, slotProps, fullWidthAtMaxSnap = false }) {
|
|
35
|
+
const storeFromContext = (0, _ariakit_react.useDialogContext)();
|
|
36
|
+
const dialogStore = controllerProp ? require_components_client_BottomSheet_useBottomSheetStore.getBottomSheetInternal(controllerProp) : storeFromContext;
|
|
37
|
+
const { backgroundColor: configBackgroundColor } = require_components_client_BottomSheet_UDSBottomSheetConfigProvider.useBottomSheetConfig();
|
|
38
|
+
if (!dialogStore) throw new Error("BottomSheet must be wrapped in BottomSheetProvider or provided a controller prop.");
|
|
39
|
+
const isOpen = dialogStore.useState().open;
|
|
40
|
+
const keyboardHeightPx = require_components_client_BottomSheet_useVirtualKeyboard.useVirtualKeyboard(isOpen);
|
|
41
|
+
const viewportHeightPx = require_components_client_BottomSheet_useViewportHeight.useViewportHeight();
|
|
42
|
+
const isDraggingRef = (0, react.useRef)(false);
|
|
43
|
+
const forceZeroMarginsRef = (0, react.useRef)(false);
|
|
44
|
+
forceZeroMarginsRef.current = keyboardHeightPx > 0;
|
|
45
|
+
const sheetRef = (0, react.useRef)(null);
|
|
46
|
+
const maxSnapPxRef = (0, react.useRef)(0);
|
|
47
|
+
const maxHeightPx = Math.max(viewportHeightPx - SHEET_MAX_HEIGHT_TOP_OFFSET_PX, 0);
|
|
48
|
+
const rootVariantClass = require_styles_styler.getStyles({ bottomsheetVariantRoot: variant });
|
|
49
|
+
const { applyExpansionMargins, thresholdRef: expansionThresholdRef } = require_components_client_BottomSheet_useExpansionMargins.useExpansionMargins({
|
|
50
|
+
sheetRef,
|
|
51
|
+
maxSnapPxRef,
|
|
52
|
+
fullWidthAtMaxSnap,
|
|
53
|
+
snapPointsLength: snapPointsProp?.length ?? 1,
|
|
54
|
+
isOpen,
|
|
55
|
+
forceZeroRef: forceZeroMarginsRef
|
|
56
|
+
});
|
|
57
|
+
/**
|
|
58
|
+
* Applies drag-time position updates with no animation.
|
|
59
|
+
* We model the sheet by height, so translate is converted to height:
|
|
60
|
+
* `height = maxSnapPointPx - translatePx`.
|
|
61
|
+
*/
|
|
62
|
+
const setTranslateImmediate = (0, react.useCallback)((nextTranslatePx) => {
|
|
63
|
+
const el = sheetRef.current;
|
|
64
|
+
if (!el) return;
|
|
65
|
+
el.style.height = `${maxSnapPxRef.current - nextTranslatePx}px`;
|
|
66
|
+
applyExpansionMargins(el, nextTranslatePx);
|
|
67
|
+
}, [applyExpansionMargins]);
|
|
68
|
+
const { resolvedSnapPoints, snapPointsPx, maxSnapPointPx, snapPointTranslatesPx, activeSnapIndex, restTranslatePx, emitSnapPointChange, openTimeRef, lastTimeDragPreventedRef, isEnteringRef } = require_components_client_BottomSheet_useBottomSheetSnapModel.useBottomSheetSnapModel({
|
|
69
|
+
isOpen,
|
|
70
|
+
snapPointsProp,
|
|
71
|
+
height,
|
|
72
|
+
defaultSnapPointIndex,
|
|
73
|
+
snapPointIndexProp,
|
|
74
|
+
onSnapPointChange,
|
|
75
|
+
viewportHeightPx,
|
|
76
|
+
maxHeightPx,
|
|
77
|
+
setTranslateAnimated: (0, react.useCallback)((nextTranslatePx) => {
|
|
78
|
+
const el = sheetRef.current;
|
|
79
|
+
if (!el) return;
|
|
80
|
+
const nextHeightPx = maxSnapPxRef.current - nextTranslatePx;
|
|
81
|
+
if (!el.style.height) {
|
|
82
|
+
el.style.height = `${nextHeightPx}px`;
|
|
83
|
+
applyExpansionMargins(el, nextTranslatePx);
|
|
84
|
+
} else {
|
|
85
|
+
const easing = "cubic-bezier(0.32, 0.72, 0, 1)";
|
|
86
|
+
let transition = `height 500ms ${easing}`;
|
|
87
|
+
if (expansionThresholdRef.current != null) transition += `, margin-left 500ms ${easing}, margin-right 500ms ${easing}, margin-bottom 500ms ${easing}`;
|
|
88
|
+
el.style.transition = transition;
|
|
89
|
+
el.style.height = `${nextHeightPx}px`;
|
|
90
|
+
applyExpansionMargins(el, nextTranslatePx);
|
|
91
|
+
const cleanup = () => {
|
|
92
|
+
el.style.removeProperty("transition");
|
|
93
|
+
el.removeEventListener("transitionend", cleanup);
|
|
94
|
+
};
|
|
95
|
+
el.addEventListener("transitionend", cleanup);
|
|
96
|
+
}
|
|
97
|
+
}, [applyExpansionMargins, expansionThresholdRef]),
|
|
98
|
+
isDraggingRef
|
|
99
|
+
});
|
|
100
|
+
maxSnapPxRef.current = maxSnapPointPx;
|
|
101
|
+
expansionThresholdRef.current = fullWidthAtMaxSnap && (snapPointsProp?.length ?? 1) >= 2 ? snapPointsPx[snapPointsPx.length - 2] ?? 0 : null;
|
|
102
|
+
const visibleTranslatePx = isOpen && !isEnteringRef.current ? 0 : viewportHeightPx;
|
|
103
|
+
const resolvedDismissThresholdPx = (snapPointsPx[0] ?? maxSnapPointPx) * DRAG_DISMISS_THRESHOLD_RATIO;
|
|
104
|
+
const shouldShowHandleIndicator = showHandleIndicator && enableDrag;
|
|
105
|
+
const isAtMaxSnapPoint = activeSnapIndex === resolvedSnapPoints.length - 1;
|
|
106
|
+
const shouldHideEdgeBordersAtMaxSnap = fullWidthAtMaxSnap && resolvedSnapPoints.length >= 2 && isAtMaxSnapPoint;
|
|
107
|
+
const handleHandleIndicatorKeyDown = (0, react.useCallback)((event) => {
|
|
108
|
+
if (!shouldShowHandleIndicator || resolvedSnapPoints.length <= 1) return;
|
|
109
|
+
if (event.key === "ArrowUp") {
|
|
110
|
+
event.preventDefault();
|
|
111
|
+
emitSnapPointChange(activeSnapIndex + 1);
|
|
112
|
+
}
|
|
113
|
+
if (event.key === "ArrowDown") {
|
|
114
|
+
event.preventDefault();
|
|
115
|
+
if (activeSnapIndex === 0 && dismissible) {
|
|
116
|
+
dialogStore.hide();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
emitSnapPointChange(activeSnapIndex - 1);
|
|
120
|
+
}
|
|
121
|
+
}, [
|
|
122
|
+
activeSnapIndex,
|
|
123
|
+
dismissible,
|
|
124
|
+
emitSnapPointChange,
|
|
125
|
+
resolvedSnapPoints.length,
|
|
126
|
+
shouldShowHandleIndicator,
|
|
127
|
+
dialogStore
|
|
128
|
+
]);
|
|
129
|
+
const { onPointerDown, onPointerMove, onPointerUp, onPointerCancel } = require_components_client_BottomSheet_useBottomSheetDrag.useBottomSheetDrag({
|
|
130
|
+
enableDrag,
|
|
131
|
+
dismissible,
|
|
132
|
+
store: dialogStore,
|
|
133
|
+
sheetRef,
|
|
134
|
+
isDraggingRef,
|
|
135
|
+
activeSnapIndex,
|
|
136
|
+
snapPointTranslatesPx,
|
|
137
|
+
maxSnapPointPx,
|
|
138
|
+
resolvedSnapPointsLength: resolvedSnapPoints.length,
|
|
139
|
+
resolvedDismissThresholdPx,
|
|
140
|
+
emitSnapPointChange,
|
|
141
|
+
setTranslateImmediate,
|
|
142
|
+
openTimeRef,
|
|
143
|
+
lastTimeDragPreventedRef
|
|
144
|
+
});
|
|
145
|
+
(0, react.useEffect)(() => {
|
|
146
|
+
if (!fullWidthAtMaxSnap || !isOpen) return;
|
|
147
|
+
const el = sheetRef.current;
|
|
148
|
+
if (!el || !el.style.height) return;
|
|
149
|
+
applyExpansionMargins(el, restTranslatePx);
|
|
150
|
+
}, [
|
|
151
|
+
restTranslatePx,
|
|
152
|
+
fullWidthAtMaxSnap,
|
|
153
|
+
isOpen,
|
|
154
|
+
applyExpansionMargins
|
|
155
|
+
]);
|
|
156
|
+
const dialogBackdrop = modal ? backdrop ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_Scrim.Scrim, {
|
|
157
|
+
className: slotProps?.scrim?.className,
|
|
158
|
+
animateOpacity: true
|
|
159
|
+
}) : false;
|
|
160
|
+
const hideOnInteractOutside = modal && dismissible ? void 0 : false;
|
|
161
|
+
const isElevationBackgroundColor = configBackgroundColor[variant].startsWith("elevation-");
|
|
162
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_ariakit_react.Dialog, {
|
|
163
|
+
ref: sheetRef,
|
|
164
|
+
store: dialogStore,
|
|
165
|
+
modal,
|
|
166
|
+
unmountOnHide: true,
|
|
167
|
+
hideOnEscape: dismissible ? hideOnEscape : false,
|
|
168
|
+
hideOnInteractOutside,
|
|
169
|
+
onClose,
|
|
170
|
+
backdrop: dialogBackdrop,
|
|
171
|
+
portal,
|
|
172
|
+
portalElement,
|
|
173
|
+
preventBodyScroll: preventBodyScroll ?? (modal ? void 0 : false),
|
|
174
|
+
"data-testid": "bottom-sheet",
|
|
175
|
+
className: require_styles_styler.cx("fixed overflow-hidden inset-x-0 bottom-0 z-50", keyboardHeightPx > 0 ? void 0 : "bottom-0", "[will-change:transform] touch-none", "[transform:translate3d(0,var(--uds-bottomsheet-hidden-translate),0)]", "data-[enter]:[transform:translate3d(0,var(--uds-bottomsheet-visible-translate),0)]", "transition-transform duration-500 ease-[cubic-bezier(0.32,0.72,0,1)]", "motion-reduce:transition-none", sheetClassName, rootVariantClass),
|
|
176
|
+
style: {
|
|
177
|
+
maxHeight: maxHeightPx ? `${maxHeightPx}px` : void 0,
|
|
178
|
+
...shouldHideEdgeBordersAtMaxSnap ? {
|
|
179
|
+
borderBottomWidth: 0,
|
|
180
|
+
borderLeftWidth: 0,
|
|
181
|
+
borderRightWidth: 0
|
|
182
|
+
} : {},
|
|
183
|
+
["--uds-bottomsheet-hidden-translate"]: `${viewportHeightPx}px`,
|
|
184
|
+
["--uds-bottomsheet-visible-translate"]: `${visibleTranslatePx}px`,
|
|
185
|
+
...isElevationBackgroundColor && {
|
|
186
|
+
backdropFilter: `var(--uds-background-blur-radius-${configBackgroundColor[variant]})`,
|
|
187
|
+
WebkitBackdropFilter: `var(--uds-background-blur-radius-${configBackgroundColor[variant]})`
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
onPointerDown,
|
|
191
|
+
onPointerMove,
|
|
192
|
+
onPointerUp,
|
|
193
|
+
onPointerCancel,
|
|
194
|
+
children: [shouldShowHandleIndicator && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_Box.Box, {
|
|
195
|
+
display: "block",
|
|
196
|
+
position: "absolute",
|
|
197
|
+
className: require_styles_styler.cx("inset-x-0 top-[-4px] z-[1] touch-pan-y"),
|
|
198
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_client_BottomSheet_BottomSheetHandle.BottomSheetHandle, {
|
|
199
|
+
onKeyDown: handleHandleIndicatorKeyDown,
|
|
200
|
+
ariaLabel: "Resize sheet",
|
|
201
|
+
className: slotProps?.handleIndicator?.className
|
|
202
|
+
})
|
|
203
|
+
}), children]
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
BottomSheet.displayName = "BottomSheet";
|
|
207
|
+
|
|
208
|
+
//#endregion
|
|
209
|
+
exports.BottomSheet = BottomSheet;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
|
|
2
|
+
import { UniversalBottomSheetProps } from "../../../types/dist/index.cjs";
|
|
3
|
+
import { BottomSheetController } from "./useBottomSheetStore.cjs";
|
|
4
|
+
import React from "react";
|
|
5
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
6
|
+
import { DialogProps } from "@ariakit/react";
|
|
7
|
+
|
|
8
|
+
//#region src/components/client/BottomSheet/BottomSheet.d.ts
|
|
9
|
+
interface BottomSheetProps extends UniversalBottomSheetProps, Pick<DialogProps, 'unmountOnHide' | 'onClose' | 'preventBodyScroll' | 'modal'> {
|
|
10
|
+
/**
|
|
11
|
+
* Controller returned from `useBottomSheetStore()`.
|
|
12
|
+
* @remarks If omitted, uses the nearest `BottomSheetProvider` context.
|
|
13
|
+
*/
|
|
14
|
+
controller?: BottomSheetController;
|
|
15
|
+
/**
|
|
16
|
+
* Determines whether the element should be rendered as a React Portal.
|
|
17
|
+
* @default true
|
|
18
|
+
*/
|
|
19
|
+
portal?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* An HTML element that returns an HTML element to be used as the portal element.
|
|
22
|
+
* By default, the portal element will be a div element appended to the document.body.
|
|
23
|
+
* @example
|
|
24
|
+
* ```jsx
|
|
25
|
+
* const [portal, setPortal] = useState(null);
|
|
26
|
+
* <BottomSheet portalElement={portalElement} />
|
|
27
|
+
* <div ref={setPortalElement} />
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
portalElement?: HTMLElement;
|
|
31
|
+
/**
|
|
32
|
+
* Determines if the dialog will hide when the user presses the Escape key.
|
|
33
|
+
*
|
|
34
|
+
* This prop can be either a boolean or a function that accepts an event as an argument and returns a boolean. The event object represents the keydown event that initiated the hide action, which could be either a native keyboard event or a React synthetic event.
|
|
35
|
+
* @default true
|
|
36
|
+
*/
|
|
37
|
+
hideOnEscape?: boolean;
|
|
38
|
+
/** Optional override for the default backdrop element passed to Ariakit Dialog. */
|
|
39
|
+
backdrop?: React.ReactElement;
|
|
40
|
+
/** Optional class hooks for internal elements. */
|
|
41
|
+
slotProps?: {
|
|
42
|
+
/** Optional className for the scrim element. */scrim?: {
|
|
43
|
+
className?: string;
|
|
44
|
+
}; /** Optional className for the handle indicator element. */
|
|
45
|
+
handleIndicator?: {
|
|
46
|
+
className?: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
declare function BottomSheet({
|
|
51
|
+
children,
|
|
52
|
+
className: sheetClassName,
|
|
53
|
+
controller: controllerProp,
|
|
54
|
+
variant,
|
|
55
|
+
snapPoints: snapPointsProp,
|
|
56
|
+
defaultSnapPointIndex,
|
|
57
|
+
snapPointIndex: snapPointIndexProp,
|
|
58
|
+
onSnapPointChange,
|
|
59
|
+
height,
|
|
60
|
+
modal,
|
|
61
|
+
portal,
|
|
62
|
+
portalElement,
|
|
63
|
+
dismissible,
|
|
64
|
+
enableDrag,
|
|
65
|
+
showHandleIndicator,
|
|
66
|
+
hideOnEscape,
|
|
67
|
+
onClose,
|
|
68
|
+
backdrop,
|
|
69
|
+
preventBodyScroll,
|
|
70
|
+
slotProps,
|
|
71
|
+
fullWidthAtMaxSnap
|
|
72
|
+
}: BottomSheetProps): react_jsx_runtime0.JSX.Element;
|
|
73
|
+
declare namespace BottomSheet {
|
|
74
|
+
var displayName: string;
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { BottomSheet, type BottomSheetProps };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
|
|
2
|
+
import { UniversalBottomSheetProps } from "../../../types/dist/index.js";
|
|
3
|
+
import { BottomSheetController } from "./useBottomSheetStore.js";
|
|
4
|
+
import React from "react";
|
|
5
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
6
|
+
import { DialogProps } from "@ariakit/react";
|
|
7
|
+
|
|
8
|
+
//#region src/components/client/BottomSheet/BottomSheet.d.ts
|
|
9
|
+
interface BottomSheetProps extends UniversalBottomSheetProps, Pick<DialogProps, 'unmountOnHide' | 'onClose' | 'preventBodyScroll' | 'modal'> {
|
|
10
|
+
/**
|
|
11
|
+
* Controller returned from `useBottomSheetStore()`.
|
|
12
|
+
* @remarks If omitted, uses the nearest `BottomSheetProvider` context.
|
|
13
|
+
*/
|
|
14
|
+
controller?: BottomSheetController;
|
|
15
|
+
/**
|
|
16
|
+
* Determines whether the element should be rendered as a React Portal.
|
|
17
|
+
* @default true
|
|
18
|
+
*/
|
|
19
|
+
portal?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* An HTML element that returns an HTML element to be used as the portal element.
|
|
22
|
+
* By default, the portal element will be a div element appended to the document.body.
|
|
23
|
+
* @example
|
|
24
|
+
* ```jsx
|
|
25
|
+
* const [portal, setPortal] = useState(null);
|
|
26
|
+
* <BottomSheet portalElement={portalElement} />
|
|
27
|
+
* <div ref={setPortalElement} />
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
portalElement?: HTMLElement;
|
|
31
|
+
/**
|
|
32
|
+
* Determines if the dialog will hide when the user presses the Escape key.
|
|
33
|
+
*
|
|
34
|
+
* This prop can be either a boolean or a function that accepts an event as an argument and returns a boolean. The event object represents the keydown event that initiated the hide action, which could be either a native keyboard event or a React synthetic event.
|
|
35
|
+
* @default true
|
|
36
|
+
*/
|
|
37
|
+
hideOnEscape?: boolean;
|
|
38
|
+
/** Optional override for the default backdrop element passed to Ariakit Dialog. */
|
|
39
|
+
backdrop?: React.ReactElement;
|
|
40
|
+
/** Optional class hooks for internal elements. */
|
|
41
|
+
slotProps?: {
|
|
42
|
+
/** Optional className for the scrim element. */scrim?: {
|
|
43
|
+
className?: string;
|
|
44
|
+
}; /** Optional className for the handle indicator element. */
|
|
45
|
+
handleIndicator?: {
|
|
46
|
+
className?: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
declare function BottomSheet({
|
|
51
|
+
children,
|
|
52
|
+
className: sheetClassName,
|
|
53
|
+
controller: controllerProp,
|
|
54
|
+
variant,
|
|
55
|
+
snapPoints: snapPointsProp,
|
|
56
|
+
defaultSnapPointIndex,
|
|
57
|
+
snapPointIndex: snapPointIndexProp,
|
|
58
|
+
onSnapPointChange,
|
|
59
|
+
height,
|
|
60
|
+
modal,
|
|
61
|
+
portal,
|
|
62
|
+
portalElement,
|
|
63
|
+
dismissible,
|
|
64
|
+
enableDrag,
|
|
65
|
+
showHandleIndicator,
|
|
66
|
+
hideOnEscape,
|
|
67
|
+
onClose,
|
|
68
|
+
backdrop,
|
|
69
|
+
preventBodyScroll,
|
|
70
|
+
slotProps,
|
|
71
|
+
fullWidthAtMaxSnap
|
|
72
|
+
}: BottomSheetProps): react_jsx_runtime0.JSX.Element;
|
|
73
|
+
declare namespace BottomSheet {
|
|
74
|
+
var displayName: string;
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { BottomSheet, type BottomSheetProps };
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
3
|
+
import { cx, getStyles } from "../../../styles/styler.js";
|
|
4
|
+
import { Box } from "../../Box.js";
|
|
5
|
+
import { Scrim } from "../../Scrim.js";
|
|
6
|
+
import { BottomSheetHandle } from "./BottomSheetHandle.js";
|
|
7
|
+
import { useBottomSheetConfig } from "./UDSBottomSheetConfigProvider.js";
|
|
8
|
+
import { useBottomSheetDrag } from "./useBottomSheetDrag.js";
|
|
9
|
+
import { useBottomSheetSnapModel } from "./useBottomSheetSnapModel.js";
|
|
10
|
+
import { getBottomSheetInternal } from "./useBottomSheetStore.js";
|
|
11
|
+
import { useExpansionMargins } from "./useExpansionMargins.js";
|
|
12
|
+
import { useViewportHeight } from "./useViewportHeight.js";
|
|
13
|
+
import { useVirtualKeyboard } from "./useVirtualKeyboard.js";
|
|
14
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
15
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
+
import { Dialog, useDialogContext } from "@ariakit/react";
|
|
17
|
+
|
|
18
|
+
//#region src/components/client/BottomSheet/BottomSheet.tsx
|
|
19
|
+
/**
|
|
20
|
+
* Drag-to-dismiss distance threshold as a ratio of the lowest snap point's
|
|
21
|
+
* visible height. Dragging down past this fraction of the height dismisses
|
|
22
|
+
* the sheet (regardless of velocity).
|
|
23
|
+
*
|
|
24
|
+
* Velocity and distance are OR conditions — exceeding either one triggers dismissal.
|
|
25
|
+
*/
|
|
26
|
+
const DRAG_DISMISS_THRESHOLD_RATIO = .25;
|
|
27
|
+
/**
|
|
28
|
+
* Top inset reserved when calculating max sheet height.
|
|
29
|
+
* Keeps a visible sliver of page content so the fully expanded state still reads as a bottom sheet.
|
|
30
|
+
*/
|
|
31
|
+
const SHEET_MAX_HEIGHT_TOP_OFFSET_PX = 26;
|
|
32
|
+
function BottomSheet({ children, className: sheetClassName, controller: controllerProp, variant = "default", snapPoints: snapPointsProp, defaultSnapPointIndex = 0, snapPointIndex: snapPointIndexProp, onSnapPointChange, height, modal = true, portal = true, portalElement, dismissible = true, enableDrag = true, showHandleIndicator = true, hideOnEscape = true, onClose, backdrop, preventBodyScroll, slotProps, fullWidthAtMaxSnap = false }) {
|
|
33
|
+
const storeFromContext = useDialogContext();
|
|
34
|
+
const dialogStore = controllerProp ? getBottomSheetInternal(controllerProp) : storeFromContext;
|
|
35
|
+
const { backgroundColor: configBackgroundColor } = useBottomSheetConfig();
|
|
36
|
+
if (!dialogStore) throw new Error("BottomSheet must be wrapped in BottomSheetProvider or provided a controller prop.");
|
|
37
|
+
const isOpen = dialogStore.useState().open;
|
|
38
|
+
const keyboardHeightPx = useVirtualKeyboard(isOpen);
|
|
39
|
+
const viewportHeightPx = useViewportHeight();
|
|
40
|
+
const isDraggingRef = useRef(false);
|
|
41
|
+
const forceZeroMarginsRef = useRef(false);
|
|
42
|
+
forceZeroMarginsRef.current = keyboardHeightPx > 0;
|
|
43
|
+
const sheetRef = useRef(null);
|
|
44
|
+
const maxSnapPxRef = useRef(0);
|
|
45
|
+
const maxHeightPx = Math.max(viewportHeightPx - SHEET_MAX_HEIGHT_TOP_OFFSET_PX, 0);
|
|
46
|
+
const rootVariantClass = getStyles({ bottomsheetVariantRoot: variant });
|
|
47
|
+
const { applyExpansionMargins, thresholdRef: expansionThresholdRef } = useExpansionMargins({
|
|
48
|
+
sheetRef,
|
|
49
|
+
maxSnapPxRef,
|
|
50
|
+
fullWidthAtMaxSnap,
|
|
51
|
+
snapPointsLength: snapPointsProp?.length ?? 1,
|
|
52
|
+
isOpen,
|
|
53
|
+
forceZeroRef: forceZeroMarginsRef
|
|
54
|
+
});
|
|
55
|
+
/**
|
|
56
|
+
* Applies drag-time position updates with no animation.
|
|
57
|
+
* We model the sheet by height, so translate is converted to height:
|
|
58
|
+
* `height = maxSnapPointPx - translatePx`.
|
|
59
|
+
*/
|
|
60
|
+
const setTranslateImmediate = useCallback((nextTranslatePx) => {
|
|
61
|
+
const el = sheetRef.current;
|
|
62
|
+
if (!el) return;
|
|
63
|
+
el.style.height = `${maxSnapPxRef.current - nextTranslatePx}px`;
|
|
64
|
+
applyExpansionMargins(el, nextTranslatePx);
|
|
65
|
+
}, [applyExpansionMargins]);
|
|
66
|
+
const { resolvedSnapPoints, snapPointsPx, maxSnapPointPx, snapPointTranslatesPx, activeSnapIndex, restTranslatePx, emitSnapPointChange, openTimeRef, lastTimeDragPreventedRef, isEnteringRef } = useBottomSheetSnapModel({
|
|
67
|
+
isOpen,
|
|
68
|
+
snapPointsProp,
|
|
69
|
+
height,
|
|
70
|
+
defaultSnapPointIndex,
|
|
71
|
+
snapPointIndexProp,
|
|
72
|
+
onSnapPointChange,
|
|
73
|
+
viewportHeightPx,
|
|
74
|
+
maxHeightPx,
|
|
75
|
+
setTranslateAnimated: useCallback((nextTranslatePx) => {
|
|
76
|
+
const el = sheetRef.current;
|
|
77
|
+
if (!el) return;
|
|
78
|
+
const nextHeightPx = maxSnapPxRef.current - nextTranslatePx;
|
|
79
|
+
if (!el.style.height) {
|
|
80
|
+
el.style.height = `${nextHeightPx}px`;
|
|
81
|
+
applyExpansionMargins(el, nextTranslatePx);
|
|
82
|
+
} else {
|
|
83
|
+
const easing = "cubic-bezier(0.32, 0.72, 0, 1)";
|
|
84
|
+
let transition = `height 500ms ${easing}`;
|
|
85
|
+
if (expansionThresholdRef.current != null) transition += `, margin-left 500ms ${easing}, margin-right 500ms ${easing}, margin-bottom 500ms ${easing}`;
|
|
86
|
+
el.style.transition = transition;
|
|
87
|
+
el.style.height = `${nextHeightPx}px`;
|
|
88
|
+
applyExpansionMargins(el, nextTranslatePx);
|
|
89
|
+
const cleanup = () => {
|
|
90
|
+
el.style.removeProperty("transition");
|
|
91
|
+
el.removeEventListener("transitionend", cleanup);
|
|
92
|
+
};
|
|
93
|
+
el.addEventListener("transitionend", cleanup);
|
|
94
|
+
}
|
|
95
|
+
}, [applyExpansionMargins, expansionThresholdRef]),
|
|
96
|
+
isDraggingRef
|
|
97
|
+
});
|
|
98
|
+
maxSnapPxRef.current = maxSnapPointPx;
|
|
99
|
+
expansionThresholdRef.current = fullWidthAtMaxSnap && (snapPointsProp?.length ?? 1) >= 2 ? snapPointsPx[snapPointsPx.length - 2] ?? 0 : null;
|
|
100
|
+
const visibleTranslatePx = isOpen && !isEnteringRef.current ? 0 : viewportHeightPx;
|
|
101
|
+
const resolvedDismissThresholdPx = (snapPointsPx[0] ?? maxSnapPointPx) * DRAG_DISMISS_THRESHOLD_RATIO;
|
|
102
|
+
const shouldShowHandleIndicator = showHandleIndicator && enableDrag;
|
|
103
|
+
const isAtMaxSnapPoint = activeSnapIndex === resolvedSnapPoints.length - 1;
|
|
104
|
+
const shouldHideEdgeBordersAtMaxSnap = fullWidthAtMaxSnap && resolvedSnapPoints.length >= 2 && isAtMaxSnapPoint;
|
|
105
|
+
const handleHandleIndicatorKeyDown = useCallback((event) => {
|
|
106
|
+
if (!shouldShowHandleIndicator || resolvedSnapPoints.length <= 1) return;
|
|
107
|
+
if (event.key === "ArrowUp") {
|
|
108
|
+
event.preventDefault();
|
|
109
|
+
emitSnapPointChange(activeSnapIndex + 1);
|
|
110
|
+
}
|
|
111
|
+
if (event.key === "ArrowDown") {
|
|
112
|
+
event.preventDefault();
|
|
113
|
+
if (activeSnapIndex === 0 && dismissible) {
|
|
114
|
+
dialogStore.hide();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
emitSnapPointChange(activeSnapIndex - 1);
|
|
118
|
+
}
|
|
119
|
+
}, [
|
|
120
|
+
activeSnapIndex,
|
|
121
|
+
dismissible,
|
|
122
|
+
emitSnapPointChange,
|
|
123
|
+
resolvedSnapPoints.length,
|
|
124
|
+
shouldShowHandleIndicator,
|
|
125
|
+
dialogStore
|
|
126
|
+
]);
|
|
127
|
+
const { onPointerDown, onPointerMove, onPointerUp, onPointerCancel } = useBottomSheetDrag({
|
|
128
|
+
enableDrag,
|
|
129
|
+
dismissible,
|
|
130
|
+
store: dialogStore,
|
|
131
|
+
sheetRef,
|
|
132
|
+
isDraggingRef,
|
|
133
|
+
activeSnapIndex,
|
|
134
|
+
snapPointTranslatesPx,
|
|
135
|
+
maxSnapPointPx,
|
|
136
|
+
resolvedSnapPointsLength: resolvedSnapPoints.length,
|
|
137
|
+
resolvedDismissThresholdPx,
|
|
138
|
+
emitSnapPointChange,
|
|
139
|
+
setTranslateImmediate,
|
|
140
|
+
openTimeRef,
|
|
141
|
+
lastTimeDragPreventedRef
|
|
142
|
+
});
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
if (!fullWidthAtMaxSnap || !isOpen) return;
|
|
145
|
+
const el = sheetRef.current;
|
|
146
|
+
if (!el || !el.style.height) return;
|
|
147
|
+
applyExpansionMargins(el, restTranslatePx);
|
|
148
|
+
}, [
|
|
149
|
+
restTranslatePx,
|
|
150
|
+
fullWidthAtMaxSnap,
|
|
151
|
+
isOpen,
|
|
152
|
+
applyExpansionMargins
|
|
153
|
+
]);
|
|
154
|
+
const dialogBackdrop = modal ? backdrop ?? /* @__PURE__ */ jsx(Scrim, {
|
|
155
|
+
className: slotProps?.scrim?.className,
|
|
156
|
+
animateOpacity: true
|
|
157
|
+
}) : false;
|
|
158
|
+
const hideOnInteractOutside = modal && dismissible ? void 0 : false;
|
|
159
|
+
const isElevationBackgroundColor = configBackgroundColor[variant].startsWith("elevation-");
|
|
160
|
+
return /* @__PURE__ */ jsxs(Dialog, {
|
|
161
|
+
ref: sheetRef,
|
|
162
|
+
store: dialogStore,
|
|
163
|
+
modal,
|
|
164
|
+
unmountOnHide: true,
|
|
165
|
+
hideOnEscape: dismissible ? hideOnEscape : false,
|
|
166
|
+
hideOnInteractOutside,
|
|
167
|
+
onClose,
|
|
168
|
+
backdrop: dialogBackdrop,
|
|
169
|
+
portal,
|
|
170
|
+
portalElement,
|
|
171
|
+
preventBodyScroll: preventBodyScroll ?? (modal ? void 0 : false),
|
|
172
|
+
"data-testid": "bottom-sheet",
|
|
173
|
+
className: cx("fixed overflow-hidden inset-x-0 bottom-0 z-50", keyboardHeightPx > 0 ? void 0 : "bottom-0", "[will-change:transform] touch-none", "[transform:translate3d(0,var(--uds-bottomsheet-hidden-translate),0)]", "data-[enter]:[transform:translate3d(0,var(--uds-bottomsheet-visible-translate),0)]", "transition-transform duration-500 ease-[cubic-bezier(0.32,0.72,0,1)]", "motion-reduce:transition-none", sheetClassName, rootVariantClass),
|
|
174
|
+
style: {
|
|
175
|
+
maxHeight: maxHeightPx ? `${maxHeightPx}px` : void 0,
|
|
176
|
+
...shouldHideEdgeBordersAtMaxSnap ? {
|
|
177
|
+
borderBottomWidth: 0,
|
|
178
|
+
borderLeftWidth: 0,
|
|
179
|
+
borderRightWidth: 0
|
|
180
|
+
} : {},
|
|
181
|
+
["--uds-bottomsheet-hidden-translate"]: `${viewportHeightPx}px`,
|
|
182
|
+
["--uds-bottomsheet-visible-translate"]: `${visibleTranslatePx}px`,
|
|
183
|
+
...isElevationBackgroundColor && {
|
|
184
|
+
backdropFilter: `var(--uds-background-blur-radius-${configBackgroundColor[variant]})`,
|
|
185
|
+
WebkitBackdropFilter: `var(--uds-background-blur-radius-${configBackgroundColor[variant]})`
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
onPointerDown,
|
|
189
|
+
onPointerMove,
|
|
190
|
+
onPointerUp,
|
|
191
|
+
onPointerCancel,
|
|
192
|
+
children: [shouldShowHandleIndicator && /* @__PURE__ */ jsx(Box, {
|
|
193
|
+
display: "block",
|
|
194
|
+
position: "absolute",
|
|
195
|
+
className: cx("inset-x-0 top-[-4px] z-[1] touch-pan-y"),
|
|
196
|
+
children: /* @__PURE__ */ jsx(BottomSheetHandle, {
|
|
197
|
+
onKeyDown: handleHandleIndicatorKeyDown,
|
|
198
|
+
ariaLabel: "Resize sheet",
|
|
199
|
+
className: slotProps?.handleIndicator?.className
|
|
200
|
+
})
|
|
201
|
+
}), children]
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
BottomSheet.displayName = "BottomSheet";
|
|
205
|
+
|
|
206
|
+
//#endregion
|
|
207
|
+
export { BottomSheet };
|