@bloomreach/react-banana-ui 1.41.0 → 1.42.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.
@@ -19,3 +19,4 @@ export declare const FieldsInRow: Story;
19
19
  export declare const OptionWithLabel: Story;
20
20
  export declare const NoneOption: Story;
21
21
  export declare const DisabledOptions: Story;
22
+ export declare const SelectWithDisabledOptions: Story<string, true>;
@@ -0,0 +1,33 @@
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
+ import { AnimationState } from './modal-utils';
3
+ import { ModalWidth } from './modal.types';
4
+ /** Props accepted by {@link ModalTransition}. */
5
+ export interface ModalTransitionProps extends HTMLAttributes<HTMLDivElement> {
6
+ /** Content to render inside the animated wrapper. */
7
+ children: ReactNode;
8
+ /** Whether the modal is in the open (entered) state. */
9
+ in: boolean;
10
+ /** Called once when the enter transition starts. */
11
+ onEnter?: () => void;
12
+ /** Called once when the exit transition has fully completed. */
13
+ onExited?: () => void;
14
+ /** Called each time the animation phase changes. */
15
+ onStateChange?: (state: AnimationState) => void;
16
+ /** Width variant forwarded as a BEM modifier class on the wrapper element. */
17
+ width: ModalWidth;
18
+ }
19
+ /**
20
+ * Internal wrapper that drives the CSS enter/exit animation for the modal.
21
+ *
22
+ * Applies `data-entering` / `data-entered` / `data-exiting` / `data-exited`
23
+ * attributes and matching BEM modifier classes so that SCSS can target each
24
+ * animation phase independently.
25
+ *
26
+ * The exit transition is also guarded by a fallback `setTimeout` so that
27
+ * `onExited` fires reliably even when the CSS `transitionend` event is
28
+ * suppressed — for example under `prefers-reduced-motion` or in jsdom tests.
29
+ *
30
+ * @internal
31
+ */
32
+ declare const ModalTransition: import('react').ForwardRefExoticComponent<ModalTransitionProps & import('react').RefAttributes<HTMLDivElement>>;
33
+ export default ModalTransition;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Fallback buffer added to the exit timeout to account for timing imprecision
3
+ * when the CSS `transitionend` event does not fire (e.g. reduced-motion, test
4
+ * environments).
5
+ */
6
+ export declare const EXIT_FALLBACK_BUFFER_MS = 20;
7
+ /**
8
+ * Default animation duration used when the CSS transition duration cannot be
9
+ * determined from the computed style of the element.
10
+ */
11
+ export declare const DEFAULT_ANIMATION_DURATION_MS = 200;
12
+ /**
13
+ * Represents the four discrete phases of a CSS enter/exit animation cycle.
14
+ *
15
+ * - `entering` — transition has been triggered but has not yet started (first rAF)
16
+ * - `entered` — element is fully visible
17
+ * - `exiting` — exit transition is in progress
18
+ * - `exited` — element is fully hidden
19
+ */
20
+ export type AnimationState = 'entered' | 'entering' | 'exited' | 'exiting';
21
+ /**
22
+ * Parses a CSS time value string into milliseconds.
23
+ *
24
+ * Handles both `ms` (e.g. `"200ms"`) and `s` (e.g. `"0.2s"`) units.
25
+ * Returns `0` for empty or unrecognised values.
26
+ *
27
+ * @param value - Raw CSS time string from `getComputedStyle`.
28
+ * @returns Duration in milliseconds.
29
+ */
30
+ export declare const parseCssTimeToMs: (value: string) => number;
31
+ /**
32
+ * Returns the maximum total transition time (duration + delay) across all CSS
33
+ * transitions applied to `element`, in milliseconds.
34
+ *
35
+ * When no positive transition time is found the function falls back to the
36
+ * `--rbui-modal-animation-duration` CSS custom property, and then to
37
+ * {@link DEFAULT_ANIMATION_DURATION_MS}.
38
+ *
39
+ * @param element - The DOM element whose computed style is inspected.
40
+ * @returns Maximum transition time in milliseconds.
41
+ */
42
+ export declare const getMaxTransitionTimeMs: (element: HTMLDivElement | null) => number;
43
+ /**
44
+ * Maps an {@link AnimationState} to a set of `data-*` attributes suitable for
45
+ * spreading onto a DOM element.
46
+ *
47
+ * Only the attribute corresponding to the current `animationState` is set to
48
+ * `true`; the remaining attributes are `undefined` so they are omitted from
49
+ * the rendered HTML.
50
+ *
51
+ * @param animationState - The current animation phase.
52
+ * @returns An object of `data-*` attribute key/value pairs.
53
+ */
54
+ export declare const getAnimationStateAttributes: (animationState: AnimationState) => Record<string, true | undefined>;
55
+ /**
56
+ * Returns a ref whose `.current` is always synchronised to the latest value of
57
+ * `value`.
58
+ *
59
+ * Useful for reading the most-recent version of a prop or callback inside a
60
+ * stable `useEffect` or `useCallback` without listing it as a dependency,
61
+ * avoiding stale-closure bugs.
62
+ *
63
+ * @param value - The value to keep up-to-date in the ref.
64
+ * @returns A mutable ref object whose `.current` mirrors `value`.
65
+ */
66
+ export declare const useLatestRef: <T>(value: T) => {
67
+ current: T;
68
+ };
@@ -1,35 +1,30 @@
1
1
  import { ModalProps } from './modal.types';
2
2
  /**
3
- * Modal component lets you create dialogs that force the user to take action before continuing
3
+ * Modal component lets you create dialogs that force the user to take action
4
+ * before continuing.
5
+ *
6
+ * The modal traps focus while open, locks the page scroll, and renders its
7
+ * content inside a {@link Portal} so it sits above all other content in the
8
+ * stacking context.
4
9
  *
5
10
  * ## Usage
6
11
  *
7
12
  * ```tsx
8
- * <Modal open>
9
- * <ModalHeader>
10
- * <ModalHeaderTitle>
11
- * Modal header
12
- * </ModalHeaderTitle>
13
- * </ModalHeader>
14
- * <ModalBody>
15
- * Design systems bridge the gap between creativity and consistency, ensuring a harmonious user experience
16
- * across platforms. By establishing a set of guidelines and components, they empower designers to craft
17
- * cohesive digital environments.
18
- * </ModalBody>
19
- * <ModalFooter>
20
- * <ModalFooterActions>
21
- * <ModalCloseButton>
22
- * Cancel
23
- * </ModalCloseButton>
24
- * <BrButton
25
- * onClick={() => {}}
26
- * type="primary"
27
- * >
28
- * Primary
29
- * </BrButton>
30
- * </ModalFooterActions>
31
- * </ModalFooter>
32
- * </Modal>
13
+ * <Modal open>
14
+ * <ModalHeader>
15
+ * <ModalHeaderTitle>Modal header</ModalHeaderTitle>
16
+ * </ModalHeader>
17
+ * <ModalBody>
18
+ * Design systems bridge the gap between creativity and consistency,
19
+ * ensuring a harmonious user experience across platforms.
20
+ * </ModalBody>
21
+ * <ModalFooter>
22
+ * <ModalFooterActions>
23
+ * <ModalCloseButton>Cancel</ModalCloseButton>
24
+ * <BrButton onClick={() => {}} type="primary">Primary</BrButton>
25
+ * </ModalFooterActions>
26
+ * </ModalFooter>
27
+ * </Modal>
33
28
  * ```
34
29
  */
35
30
  declare const Modal: import('react').ForwardRefExoticComponent<ModalProps & import('react').RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,32 @@
1
+ import { AnimationState } from './modal-utils';
2
+ /** Options accepted by {@link useModalPresence}. */
3
+ interface UseModalPresenceOptions {
4
+ /** Whether the modal's DOM tree should be kept in the document after closing. */
5
+ keepMounted: boolean;
6
+ /** Whether the modal is currently open. */
7
+ open: boolean;
8
+ }
9
+ /** Return value of {@link useModalPresence}. */
10
+ interface UseModalPresenceResult {
11
+ /** Current animation phase of the modal. */
12
+ animationState: AnimationState;
13
+ /** Callback to advance the animation state; also drives the mount/unmount lifecycle. */
14
+ handleAnimationStateChange: (state: AnimationState) => void;
15
+ /** Whether the modal's subtree should be rendered into the DOM. */
16
+ isMounted: boolean;
17
+ }
18
+ /**
19
+ * Manages the mounted/unmounted lifecycle and animation state of a modal.
20
+ *
21
+ * The modal is kept in the DOM while it is open or while `keepMounted` is
22
+ * `true`. Once the exit animation completes (i.e. `animationState` reaches
23
+ * `"exited"`) and `keepMounted` is `false`, the modal is unmounted.
24
+ *
25
+ * @param options - Configuration for keep-mounted behaviour and open state.
26
+ * @param options.keepMounted - Whether the modal DOM tree should be retained after closing.
27
+ * @param options.open - Whether the modal is currently open.
28
+ * @returns The current animation state, a state-change handler, and a flag
29
+ * indicating whether the modal subtree should be mounted.
30
+ */
31
+ export declare const useModalPresence: ({ keepMounted, open }: UseModalPresenceOptions) => UseModalPresenceResult;
32
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bloomreach/react-banana-ui",
3
3
  "type": "module",
4
- "version": "1.41.0",
4
+ "version": "1.42.1",
5
5
  "private": false,
6
6
  "repository": {
7
7
  "type": "git",