@webority-technologies/mobile 0.0.21 → 0.0.22

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.
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = exports.BottomSheet = void 0;
6
+ exports.useBottomSheet = exports.default = exports.BottomSheet = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _reactNativeGestureHandler = require("react-native-gesture-handler");
@@ -32,6 +32,33 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
32
32
  * ref.current?.close(); // dismiss
33
33
  */
34
34
 
35
+ /**
36
+ * State + actions exposed to anything rendered inside a `<BottomSheet>` —
37
+ * including the `header` and `footer` slots. Read via `useBottomSheet()`.
38
+ *
39
+ * `snapIndex` is the JS-thread mirror of the current snap point. -1 means the
40
+ * sheet is closed (mid-close-animation included). Use it to drive footer
41
+ * button enable state, conditional headers, etc. If you need per-frame
42
+ * progress (e.g. fade a header in as the sheet expands), reach for the
43
+ * animated value via a future enhancement — not exposed today to keep the
44
+ * surface minimal.
45
+ */
46
+
47
+ const BottomSheetContext = /*#__PURE__*/(0, _react.createContext)(null);
48
+
49
+ /**
50
+ * Access the enclosing `<BottomSheet>`'s state and imperative actions.
51
+ * Must be called from a component rendered inside a `<BottomSheet>` (as
52
+ * `children`, `header`, or `footer`).
53
+ */
54
+ const useBottomSheet = () => {
55
+ const ctx = (0, _react.useContext)(BottomSheetContext);
56
+ if (!ctx) {
57
+ throw new Error('useBottomSheet must be used inside a <BottomSheet>.');
58
+ }
59
+ return ctx;
60
+ };
61
+ exports.useBottomSheet = useBottomSheet;
35
62
  const SPRING_CONFIG = {
36
63
  damping: 20,
37
64
  stiffness: 240,
@@ -51,6 +78,10 @@ const BottomSheet = exports.BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((p
51
78
  mode = 'modal',
52
79
  handleIndicatorStyle,
53
80
  containerStyle,
81
+ header,
82
+ footer,
83
+ headerStyle,
84
+ footerStyle,
54
85
  children,
55
86
  accessibilityLabel,
56
87
  accessibilityViewIsModal,
@@ -336,6 +367,13 @@ const BottomSheet = exports.BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((p
336
367
  if (!success) return;
337
368
  (0, _reactNativeReanimated.runOnJS)(handleBackdropPress)();
338
369
  }), [handleBackdropPress]);
370
+ const contextValue = (0, _react.useMemo)(() => ({
371
+ snapIndex: currentIndex,
372
+ snapPoints: resolvedSnapPoints,
373
+ expand,
374
+ collapse,
375
+ close
376
+ }), [currentIndex, resolvedSnapPoints, expand, collapse, close]);
339
377
 
340
378
  // Don't render the backdrop / sheet tree when the sheet is fully closed.
341
379
  // Inline: gated by `inlineMounted` (set in expand, cleared in
@@ -389,13 +427,23 @@ const BottomSheet = exports.BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((p
389
427
  backgroundColor: theme.components.bottomSheet?.handleColor ?? theme.colors.border.primary
390
428
  }, handleIndicatorStyle]
391
429
  })
430
+ }), header != null && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
431
+ style: [styles.header, headerStyle],
432
+ children: header
392
433
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
393
434
  style: styles.content,
394
435
  children: children
436
+ }), footer != null && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
437
+ style: [styles.footer, footerStyle],
438
+ children: footer
395
439
  })]
396
440
  })
397
441
  })]
398
442
  });
443
+ const wrappedTree = /*#__PURE__*/(0, _jsxRuntime.jsx)(BottomSheetContext.Provider, {
444
+ value: contextValue,
445
+ children: sheetTree
446
+ });
399
447
  if (mode === 'modal') {
400
448
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Modal, {
401
449
  transparent: true,
@@ -410,11 +458,11 @@ const BottomSheet = exports.BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((p
410
458
  supportedOrientations: ['portrait', 'landscape'],
411
459
  children: _reactNative.Platform.OS === 'android' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureHandlerRootView, {
412
460
  style: styles.modalRoot,
413
- children: sheetTree
414
- }) : sheetTree
461
+ children: wrappedTree
462
+ }) : wrappedTree
415
463
  });
416
464
  }
417
- return sheetTree;
465
+ return wrappedTree;
418
466
  });
419
467
  BottomSheet.displayName = 'BottomSheet';
420
468
 
@@ -459,6 +507,15 @@ const buildStyles = _theme => _reactNative.StyleSheet.create({
459
507
  paddingTop: 10,
460
508
  paddingBottom: 8
461
509
  },
510
+ header: {
511
+ // No opinionated padding — slot owns its own styling. Sits between the
512
+ // drag handle and the scrollable content; does not flex.
513
+ },
514
+ footer: {
515
+ // Pinned to the bottom of the sheet (above safe-area inset, which lives
516
+ // on the sheet's paddingBottom). Does not flex, does not scroll with
517
+ // content. Rides with the keyboard via the sheet's `top` animation.
518
+ },
462
519
  handle: {
463
520
  width: 36,
464
521
  height: 4,
@@ -15,6 +15,12 @@ Object.defineProperty(exports, "default", {
15
15
  return _BottomSheet.default;
16
16
  }
17
17
  });
18
+ Object.defineProperty(exports, "useBottomSheet", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _BottomSheet.useBottomSheet;
22
+ }
23
+ });
18
24
  var _BottomSheet = _interopRequireWildcard(require("./BottomSheet.js"));
19
25
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
20
26
  //# sourceMappingURL=index.js.map
@@ -345,6 +345,12 @@ Object.defineProperty(exports, "toast", {
345
345
  return _index41.toast;
346
346
  }
347
347
  });
348
+ Object.defineProperty(exports, "useBottomSheet", {
349
+ enumerable: true,
350
+ get: function () {
351
+ return _index6.useBottomSheet;
352
+ }
353
+ });
348
354
  Object.defineProperty(exports, "useReduceMotion", {
349
355
  enumerable: true,
350
356
  get: function () {
@@ -19,14 +19,40 @@
19
19
  * ref.current?.close(); // dismiss
20
20
  */
21
21
 
22
- import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
22
+ import React, { createContext, forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
23
23
  import { Dimensions, Keyboard, Modal, Platform, StyleSheet, View } from 'react-native';
24
24
  import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler';
25
25
  import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';
26
26
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
27
27
  import { useTheme } from "../../theme/index.js";
28
28
  import { triggerHaptic } from "../../utils/index.js";
29
+
30
+ /**
31
+ * State + actions exposed to anything rendered inside a `<BottomSheet>` —
32
+ * including the `header` and `footer` slots. Read via `useBottomSheet()`.
33
+ *
34
+ * `snapIndex` is the JS-thread mirror of the current snap point. -1 means the
35
+ * sheet is closed (mid-close-animation included). Use it to drive footer
36
+ * button enable state, conditional headers, etc. If you need per-frame
37
+ * progress (e.g. fade a header in as the sheet expands), reach for the
38
+ * animated value via a future enhancement — not exposed today to keep the
39
+ * surface minimal.
40
+ */
29
41
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
42
+ const BottomSheetContext = /*#__PURE__*/createContext(null);
43
+
44
+ /**
45
+ * Access the enclosing `<BottomSheet>`'s state and imperative actions.
46
+ * Must be called from a component rendered inside a `<BottomSheet>` (as
47
+ * `children`, `header`, or `footer`).
48
+ */
49
+ export const useBottomSheet = () => {
50
+ const ctx = useContext(BottomSheetContext);
51
+ if (!ctx) {
52
+ throw new Error('useBottomSheet must be used inside a <BottomSheet>.');
53
+ }
54
+ return ctx;
55
+ };
30
56
  const SPRING_CONFIG = {
31
57
  damping: 20,
32
58
  stiffness: 240,
@@ -46,6 +72,10 @@ const BottomSheet = /*#__PURE__*/forwardRef((props, ref) => {
46
72
  mode = 'modal',
47
73
  handleIndicatorStyle,
48
74
  containerStyle,
75
+ header,
76
+ footer,
77
+ headerStyle,
78
+ footerStyle,
49
79
  children,
50
80
  accessibilityLabel,
51
81
  accessibilityViewIsModal,
@@ -331,6 +361,13 @@ const BottomSheet = /*#__PURE__*/forwardRef((props, ref) => {
331
361
  if (!success) return;
332
362
  runOnJS(handleBackdropPress)();
333
363
  }), [handleBackdropPress]);
364
+ const contextValue = useMemo(() => ({
365
+ snapIndex: currentIndex,
366
+ snapPoints: resolvedSnapPoints,
367
+ expand,
368
+ collapse,
369
+ close
370
+ }), [currentIndex, resolvedSnapPoints, expand, collapse, close]);
334
371
 
335
372
  // Don't render the backdrop / sheet tree when the sheet is fully closed.
336
373
  // Inline: gated by `inlineMounted` (set in expand, cleared in
@@ -384,13 +421,23 @@ const BottomSheet = /*#__PURE__*/forwardRef((props, ref) => {
384
421
  backgroundColor: theme.components.bottomSheet?.handleColor ?? theme.colors.border.primary
385
422
  }, handleIndicatorStyle]
386
423
  })
424
+ }), header != null && /*#__PURE__*/_jsx(View, {
425
+ style: [styles.header, headerStyle],
426
+ children: header
387
427
  }), /*#__PURE__*/_jsx(View, {
388
428
  style: styles.content,
389
429
  children: children
430
+ }), footer != null && /*#__PURE__*/_jsx(View, {
431
+ style: [styles.footer, footerStyle],
432
+ children: footer
390
433
  })]
391
434
  })
392
435
  })]
393
436
  });
437
+ const wrappedTree = /*#__PURE__*/_jsx(BottomSheetContext.Provider, {
438
+ value: contextValue,
439
+ children: sheetTree
440
+ });
394
441
  if (mode === 'modal') {
395
442
  return /*#__PURE__*/_jsx(Modal, {
396
443
  transparent: true,
@@ -405,11 +452,11 @@ const BottomSheet = /*#__PURE__*/forwardRef((props, ref) => {
405
452
  supportedOrientations: ['portrait', 'landscape'],
406
453
  children: Platform.OS === 'android' ? /*#__PURE__*/_jsx(GestureHandlerRootView, {
407
454
  style: styles.modalRoot,
408
- children: sheetTree
409
- }) : sheetTree
455
+ children: wrappedTree
456
+ }) : wrappedTree
410
457
  });
411
458
  }
412
- return sheetTree;
459
+ return wrappedTree;
413
460
  });
414
461
  BottomSheet.displayName = 'BottomSheet';
415
462
 
@@ -454,6 +501,15 @@ const buildStyles = _theme => StyleSheet.create({
454
501
  paddingTop: 10,
455
502
  paddingBottom: 8
456
503
  },
504
+ header: {
505
+ // No opinionated padding — slot owns its own styling. Sits between the
506
+ // drag handle and the scrollable content; does not flex.
507
+ },
508
+ footer: {
509
+ // Pinned to the bottom of the sheet (above safe-area inset, which lives
510
+ // on the sheet's paddingBottom). Does not flex, does not scroll with
511
+ // content. Rides with the keyboard via the sheet's `top` animation.
512
+ },
457
513
  handle: {
458
514
  width: 36,
459
515
  height: 4,
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
 
3
- export { BottomSheet, default } from "./BottomSheet.js";
3
+ export { BottomSheet, default, useBottomSheet } from "./BottomSheet.js";
4
4
  //# sourceMappingURL=index.js.map
@@ -5,7 +5,7 @@ export { Avatar, AvatarGroup } from "./Avatar/index.js";
5
5
  export { Badge } from "./Badge/index.js";
6
6
  export { Banner } from "./Banner/index.js";
7
7
  export { BottomNavigation } from "./BottomNavigation/index.js";
8
- export { BottomSheet } from "./BottomSheet/index.js";
8
+ export { BottomSheet, useBottomSheet } from "./BottomSheet/index.js";
9
9
  export { Button } from "./Button/index.js";
10
10
  export { Card } from "./Card/index.js";
11
11
  export { Carousel } from "./Carousel/index.js";
@@ -56,6 +56,23 @@ export interface BottomSheetProps {
56
56
  mode?: BottomSheetMode;
57
57
  handleIndicatorStyle?: StyleProp<ViewStyle>;
58
58
  containerStyle?: StyleProp<ViewStyle>;
59
+ /**
60
+ * Sticky region rendered between the drag handle and the scrollable content.
61
+ * Does not scroll with `children`. Can call `useBottomSheet()` to read sheet
62
+ * state.
63
+ */
64
+ header?: React.ReactNode;
65
+ /**
66
+ * Sticky region pinned to the bottom of the sheet, above the safe-area
67
+ * inset. Does not scroll with `children`, and rides up with the keyboard
68
+ * when `keyboardBehavior='shift'` (no extra wiring needed — the whole sheet
69
+ * shifts). Typical use: action button rows.
70
+ */
71
+ footer?: React.ReactNode;
72
+ /** Style applied to the header region wrapper. */
73
+ headerStyle?: StyleProp<ViewStyle>;
74
+ /** Style applied to the footer region wrapper. */
75
+ footerStyle?: StyleProp<ViewStyle>;
59
76
  children?: React.ReactNode;
60
77
  accessibilityLabel?: string;
61
78
  accessibilityViewIsModal?: boolean;
@@ -66,6 +83,30 @@ export interface BottomSheetRef {
66
83
  collapse: () => void;
67
84
  close: () => void;
68
85
  }
86
+ /**
87
+ * State + actions exposed to anything rendered inside a `<BottomSheet>` —
88
+ * including the `header` and `footer` slots. Read via `useBottomSheet()`.
89
+ *
90
+ * `snapIndex` is the JS-thread mirror of the current snap point. -1 means the
91
+ * sheet is closed (mid-close-animation included). Use it to drive footer
92
+ * button enable state, conditional headers, etc. If you need per-frame
93
+ * progress (e.g. fade a header in as the sheet expands), reach for the
94
+ * animated value via a future enhancement — not exposed today to keep the
95
+ * surface minimal.
96
+ */
97
+ export interface BottomSheetContextValue {
98
+ snapIndex: number;
99
+ snapPoints: number[];
100
+ expand: (index?: number) => void;
101
+ collapse: () => void;
102
+ close: () => void;
103
+ }
104
+ /**
105
+ * Access the enclosing `<BottomSheet>`'s state and imperative actions.
106
+ * Must be called from a component rendered inside a `<BottomSheet>` (as
107
+ * `children`, `header`, or `footer`).
108
+ */
109
+ export declare const useBottomSheet: () => BottomSheetContextValue;
69
110
  declare const BottomSheet: React.ForwardRefExoticComponent<BottomSheetProps & React.RefAttributes<BottomSheetRef>>;
70
111
  export { BottomSheet };
71
112
  export default BottomSheet;
@@ -1,3 +1,3 @@
1
- export { BottomSheet, default } from './BottomSheet';
2
- export type { BottomSheetProps, BottomSheetRef, SnapPoint } from './BottomSheet';
1
+ export { BottomSheet, default, useBottomSheet } from './BottomSheet';
2
+ export type { BottomSheetContextValue, BottomSheetProps, BottomSheetRef, SnapPoint } from './BottomSheet';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -8,8 +8,8 @@ export { Banner } from './Banner';
8
8
  export type { BannerProps, BannerVariant, BannerAction } from './Banner';
9
9
  export { BottomNavigation } from './BottomNavigation';
10
10
  export type { BottomNavigationProps, TabConfig } from './BottomNavigation';
11
- export { BottomSheet } from './BottomSheet';
12
- export type { BottomSheetProps, BottomSheetRef } from './BottomSheet';
11
+ export { BottomSheet, useBottomSheet } from './BottomSheet';
12
+ export type { BottomSheetContextValue, BottomSheetProps, BottomSheetRef } from './BottomSheet';
13
13
  export { Button } from './Button';
14
14
  export type { ButtonProps, ButtonVariant, ButtonTone, ButtonSize } from './Button';
15
15
  export { Card } from './Card';
@@ -56,6 +56,23 @@ export interface BottomSheetProps {
56
56
  mode?: BottomSheetMode;
57
57
  handleIndicatorStyle?: StyleProp<ViewStyle>;
58
58
  containerStyle?: StyleProp<ViewStyle>;
59
+ /**
60
+ * Sticky region rendered between the drag handle and the scrollable content.
61
+ * Does not scroll with `children`. Can call `useBottomSheet()` to read sheet
62
+ * state.
63
+ */
64
+ header?: React.ReactNode;
65
+ /**
66
+ * Sticky region pinned to the bottom of the sheet, above the safe-area
67
+ * inset. Does not scroll with `children`, and rides up with the keyboard
68
+ * when `keyboardBehavior='shift'` (no extra wiring needed — the whole sheet
69
+ * shifts). Typical use: action button rows.
70
+ */
71
+ footer?: React.ReactNode;
72
+ /** Style applied to the header region wrapper. */
73
+ headerStyle?: StyleProp<ViewStyle>;
74
+ /** Style applied to the footer region wrapper. */
75
+ footerStyle?: StyleProp<ViewStyle>;
59
76
  children?: React.ReactNode;
60
77
  accessibilityLabel?: string;
61
78
  accessibilityViewIsModal?: boolean;
@@ -66,6 +83,30 @@ export interface BottomSheetRef {
66
83
  collapse: () => void;
67
84
  close: () => void;
68
85
  }
86
+ /**
87
+ * State + actions exposed to anything rendered inside a `<BottomSheet>` —
88
+ * including the `header` and `footer` slots. Read via `useBottomSheet()`.
89
+ *
90
+ * `snapIndex` is the JS-thread mirror of the current snap point. -1 means the
91
+ * sheet is closed (mid-close-animation included). Use it to drive footer
92
+ * button enable state, conditional headers, etc. If you need per-frame
93
+ * progress (e.g. fade a header in as the sheet expands), reach for the
94
+ * animated value via a future enhancement — not exposed today to keep the
95
+ * surface minimal.
96
+ */
97
+ export interface BottomSheetContextValue {
98
+ snapIndex: number;
99
+ snapPoints: number[];
100
+ expand: (index?: number) => void;
101
+ collapse: () => void;
102
+ close: () => void;
103
+ }
104
+ /**
105
+ * Access the enclosing `<BottomSheet>`'s state and imperative actions.
106
+ * Must be called from a component rendered inside a `<BottomSheet>` (as
107
+ * `children`, `header`, or `footer`).
108
+ */
109
+ export declare const useBottomSheet: () => BottomSheetContextValue;
69
110
  declare const BottomSheet: React.ForwardRefExoticComponent<BottomSheetProps & React.RefAttributes<BottomSheetRef>>;
70
111
  export { BottomSheet };
71
112
  export default BottomSheet;
@@ -1,3 +1,3 @@
1
- export { BottomSheet, default } from './BottomSheet';
2
- export type { BottomSheetProps, BottomSheetRef, SnapPoint } from './BottomSheet';
1
+ export { BottomSheet, default, useBottomSheet } from './BottomSheet';
2
+ export type { BottomSheetContextValue, BottomSheetProps, BottomSheetRef, SnapPoint } from './BottomSheet';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -8,8 +8,8 @@ export { Banner } from './Banner';
8
8
  export type { BannerProps, BannerVariant, BannerAction } from './Banner';
9
9
  export { BottomNavigation } from './BottomNavigation';
10
10
  export type { BottomNavigationProps, TabConfig } from './BottomNavigation';
11
- export { BottomSheet } from './BottomSheet';
12
- export type { BottomSheetProps, BottomSheetRef } from './BottomSheet';
11
+ export { BottomSheet, useBottomSheet } from './BottomSheet';
12
+ export type { BottomSheetContextValue, BottomSheetProps, BottomSheetRef } from './BottomSheet';
13
13
  export { Button } from './Button';
14
14
  export type { ButtonProps, ButtonVariant, ButtonTone, ButtonSize } from './Button';
15
15
  export { Card } from './Card';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webority-technologies/mobile",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "description": "Beautiful, animated, accessible React Native components plus API/auth/logging/network/storage utilities for Webority projects.",
5
5
  "keywords": [
6
6
  "react-native",