reshaped 3.3.13 → 3.4.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/bundle.css +1 -1
  3. package/dist/bundle.d.ts +3 -0
  4. package/dist/bundle.js +11 -11
  5. package/dist/components/Autocomplete/Autocomplete.js +34 -24
  6. package/dist/components/Autocomplete/Autocomplete.types.d.ts +1 -1
  7. package/dist/components/Autocomplete/tests/Autocomplete.stories.js +8 -1
  8. package/dist/components/Carousel/Carousel.js +2 -1
  9. package/dist/components/Carousel/Carousel.types.d.ts +1 -0
  10. package/dist/components/ContextMenu/ContextMenu.js +2 -2
  11. package/dist/components/ContextMenu/tests/ContextMenu.test.stories.js +1 -1
  12. package/dist/components/DropdownMenu/DropdownMenu.js +6 -1
  13. package/dist/components/DropdownMenu/tests/DropdownMenu.test.stories.js +2 -2
  14. package/dist/components/Popover/Popover.js +1 -1
  15. package/dist/components/Popover/tests/Popover.test.stories.js +4 -4
  16. package/dist/components/ProgressIndicator/ProgressIndicator.d.ts +3 -0
  17. package/dist/components/ProgressIndicator/ProgressIndicator.js +101 -0
  18. package/dist/components/ProgressIndicator/ProgressIndicator.module.css +1 -0
  19. package/dist/components/ProgressIndicator/ProgressIndicator.types.d.ts +9 -0
  20. package/dist/components/ProgressIndicator/ProgressIndicator.types.js +1 -0
  21. package/dist/components/ProgressIndicator/index.d.ts +2 -0
  22. package/dist/components/ProgressIndicator/index.js +1 -0
  23. package/dist/components/ProgressIndicator/tests/ProgressIndicator.stories.d.ts +19 -0
  24. package/dist/components/ProgressIndicator/tests/ProgressIndicator.stories.js +85 -0
  25. package/dist/components/Reshaped/Reshaped.js +4 -5
  26. package/dist/components/TextField/TextField.module.css +1 -1
  27. package/dist/components/Toast/tests/Toast.stories.js +22 -7
  28. package/dist/components/Tooltip/tests/Tooltip.test.stories.js +1 -1
  29. package/dist/components/_private/Flyout/Flyout.module.css +1 -1
  30. package/dist/components/_private/Flyout/Flyout.types.d.ts +14 -3
  31. package/dist/components/_private/Flyout/FlyoutContent.js +37 -7
  32. package/dist/components/_private/Flyout/FlyoutControlled.js +12 -11
  33. package/dist/components/_private/Flyout/FlyoutUncontrolled.js +3 -5
  34. package/dist/components/_private/Flyout/index.d.ts +1 -1
  35. package/dist/components/_private/Flyout/tests/Flyout.stories.d.ts +79 -13
  36. package/dist/components/_private/Flyout/tests/Flyout.stories.js +526 -280
  37. package/dist/components/_private/Flyout/useFlyout.js +9 -3
  38. package/dist/components/_private/Flyout/utilities/isFullyVisible.d.ts +3 -1
  39. package/dist/components/_private/Flyout/utilities/isFullyVisible.js +2 -2
  40. package/dist/hooks/_private/usePrevious.d.ts +2 -0
  41. package/dist/hooks/_private/usePrevious.js +17 -0
  42. package/dist/hooks/_private/useSingletonEnvironment.d.ts +1 -1
  43. package/dist/hooks/_private/useSingletonEnvironment.js +1 -1
  44. package/dist/hooks/_private/useSingletonKeyboardMode.d.ts +13 -2
  45. package/dist/hooks/_private/useSingletonKeyboardMode.js +48 -15
  46. package/dist/hooks/tests/useKeyboardMode.stories.d.ts +6 -0
  47. package/dist/hooks/tests/useKeyboardMode.stories.js +37 -0
  48. package/dist/hooks/useKeyboardMode.d.ts +7 -0
  49. package/dist/hooks/useKeyboardMode.js +13 -0
  50. package/dist/index.d.ts +3 -0
  51. package/dist/index.js +2 -0
  52. package/dist/utilities/a11y/index.d.ts +1 -1
  53. package/dist/utilities/a11y/index.js +1 -1
  54. package/dist/utilities/a11y/keyboardMode.d.ts +2 -2
  55. package/dist/utilities/a11y/keyboardMode.js +2 -2
  56. package/dist/utilities/dom/find.d.ts +4 -1
  57. package/dist/utilities/dom/find.js +4 -4
  58. package/dist/utilities/scroll/lockStandard.js +1 -1
  59. package/package.json +3 -4
  60. package/dist/components/_private/Flyout/tests/Flyout.test.stories.d.ts +0 -28
  61. package/dist/components/_private/Flyout/tests/Flyout.test.stories.js +0 -205
@@ -9,22 +9,47 @@ import useHotkeys from "../../hooks/useHotkeys.js";
9
9
  import useHandlerRef from "../../hooks/useHandlerRef.js";
10
10
  const AutocompleteContext = React.createContext({});
11
11
  const Autocomplete = (props) => {
12
- const { children, onChange, onInput, onItemSelect, name, containerRef, instanceRef, onBackspace, ...textFieldProps } = props;
12
+ const { children, onChange, onInput, onItemSelect, name, containerRef, instanceRef, onBackspace, active, onOpen, onClose, ...textFieldProps } = props;
13
13
  const onBackspaceRef = useHandlerRef(onBackspace);
14
14
  const internalInputRef = React.useRef(null);
15
15
  const inputAttributesRef = textFieldProps.inputAttributes?.ref;
16
16
  const inputRef = inputAttributesRef && typeof inputAttributesRef !== "string" && "current" in inputAttributesRef
17
17
  ? inputAttributesRef
18
18
  : internalInputRef;
19
- const [active, setActive] = React.useState(false);
19
+ const [internalActive, setInternalActive] = React.useState(false);
20
20
  const hasChildren = !!React.Children.toArray(children).filter(Boolean).length;
21
21
  const lockedRef = React.useRef(false);
22
+ const onOpenRef = useHandlerRef(onOpen);
23
+ const onCloseRef = useHandlerRef(onClose);
24
+ const isDropdownActive = hasChildren && (active ?? internalActive);
22
25
  const handleOpen = React.useCallback(() => {
23
26
  if (lockedRef.current)
24
27
  return;
25
- setActive(true);
26
- }, []);
27
- const handleClose = () => setActive(false);
28
+ setInternalActive(true);
29
+ onOpenRef.current?.();
30
+ }, [onOpenRef]);
31
+ const handleClose = (args) => {
32
+ setInternalActive(false);
33
+ onCloseRef.current?.(args);
34
+ };
35
+ const handleItemClick = (args) => {
36
+ onChange?.({ value: args.value, name });
37
+ onItemSelect?.(args);
38
+ // Prevent dropdown from re-opening when clicked on item with mouse
39
+ // and focus moves to the item and back to the input
40
+ lockedRef.current = true;
41
+ setTimeout(() => {
42
+ lockedRef.current = false;
43
+ }, 100);
44
+ };
45
+ const handleChange = (args) => {
46
+ onChange?.(args);
47
+ handleOpen();
48
+ };
49
+ const handleInput = (e) => {
50
+ onInput?.({ value: e.currentTarget.value, name, event: e });
51
+ textFieldProps.inputAttributes?.onInput?.(e);
52
+ };
28
53
  useHotkeys({
29
54
  [keys.BACKSPACE]: () => {
30
55
  onBackspaceRef.current?.();
@@ -42,26 +67,9 @@ const Autocomplete = (props) => {
42
67
  el?.click();
43
68
  },
44
69
  }, [handleOpen], { ref: inputRef, preventDefault: true });
45
- const handleChange = (args) => {
46
- onChange?.(args);
47
- handleOpen();
48
- };
49
- const handleItemClick = (args) => {
50
- onChange?.({ value: args.value, name });
51
- onItemSelect?.(args);
52
- // Prevent dropdown from re-opening when clicked on item with mouse
53
- // and focus moves to the item and back to the input
54
- lockedRef.current = true;
55
- setTimeout(() => (lockedRef.current = false), 100);
56
- };
57
- const handleInput = (e) => {
58
- onInput?.({ value: e.currentTarget.value, name, event: e });
59
- textFieldProps.inputAttributes?.onInput?.(e);
60
- };
61
- return (_jsx(AutocompleteContext.Provider, { value: { onItemClick: handleItemClick }, children: _jsxs(DropdownMenu, { position: "bottom", width: "trigger", triggerType: "focus", trapFocusMode: "selection-menu", active: hasChildren && active, onClose: handleClose, onOpen: handleOpen, containerRef: containerRef, disableHideAnimation: true, instanceRef: instanceRef, children: [_jsx(DropdownMenu.Trigger, { children: ({ ref, ...attributes }) => (_jsx(TextField, { ...textFieldProps, name: name, onChange: handleChange, focused: hasChildren && active,
62
- // Ignoring the type check since TS can't infer the correct html element type
63
- attributes: {
70
+ return (_jsx(AutocompleteContext.Provider, { value: { onItemClick: handleItemClick }, children: _jsxs(DropdownMenu, { position: "bottom", width: "trigger", triggerType: "focus", trapFocusMode: "selection-menu", active: isDropdownActive, onClose: handleClose, onOpen: handleOpen, containerRef: containerRef, disableHideAnimation: true, instanceRef: instanceRef, children: [_jsx(DropdownMenu.Trigger, { children: ({ ref, ...attributes }) => (_jsx(TextField, { ...textFieldProps, name: name, onChange: handleChange, focused: isDropdownActive, attributes: {
64
71
  ...textFieldProps.attributes,
72
+ // Ignoring the type check since TS can't infer the correct html element type
65
73
  ref: ref,
66
74
  onClick: attributes.onFocus,
67
75
  }, inputAttributes: {
@@ -70,6 +78,8 @@ const Autocomplete = (props) => {
70
78
  onFocus: (e) => {
71
79
  attributes.onFocus?.();
72
80
  textFieldProps.onFocus?.(e);
81
+ if (!lockedRef.current)
82
+ inputRef.current?.select();
73
83
  },
74
84
  onInput: handleInput,
75
85
  onClick: attributes.onFocus,
@@ -5,7 +5,7 @@ type SelectArgs = {
5
5
  value: string;
6
6
  data?: unknown;
7
7
  };
8
- export type Props = TextFieldProps & Pick<DropdownMenuProps, "containerRef" | "instanceRef"> & {
8
+ export type Props = TextFieldProps & Pick<DropdownMenuProps, "containerRef" | "instanceRef" | "active" | "onOpen" | "onClose"> & {
9
9
  onInput?: TextFieldProps["onChange"];
10
10
  onItemSelect?: (args: SelectArgs) => void;
11
11
  onBackspace?: () => void;
@@ -44,6 +44,7 @@ export const multiselect = {
44
44
  name: "multiselect",
45
45
  render: () => {
46
46
  const inputRef = React.useRef(null);
47
+ const [active, setActive] = React.useState(false);
47
48
  const [values, setValues] = React.useState(["foo", "bar"]);
48
49
  const [query, setQuery] = React.useState("");
49
50
  const [customValueQuery, setCustomValueQuery] = React.useState("");
@@ -70,7 +71,13 @@ export const multiselect = {
70
71
  <Autocomplete name="fruit" value={query} placeholder="Pick your food" startSlot={valuesNode} inputAttributes={{ ref: inputRef }} onBackspace={() => {
71
72
  if (!query.length)
72
73
  handleDismiss(values[values.length - 1]);
73
- }} multiline onChange={(args) => setQuery(args.value)} onItemSelect={(args) => {
74
+ }} onOpen={() => {
75
+ setActive(true);
76
+ }} onClose={(args) => {
77
+ if (args.reason === "item-selection")
78
+ return;
79
+ setActive(false);
80
+ }} active={active} multiline onChange={(args) => setQuery(args.value)} onItemSelect={(args) => {
74
81
  setCustomValueQuery(query);
75
82
  setQuery("");
76
83
  if (args.value === "_custom") {
@@ -9,7 +9,7 @@ import CarouselControl from "./CarouselControl.js";
9
9
  import * as T from "./Carousel.types.js";
10
10
  import s from "./Carousel.module.css";
11
11
  const Carousel = (props) => {
12
- const { children, gap = 3, visibleItems, bleed, navigationDisplay, onChange, instanceRef, className, attributes, } = props;
12
+ const { children, gap = 3, visibleItems, bleed, navigationDisplay, onChange, onScroll, instanceRef, className, attributes, } = props;
13
13
  const currentIndexRef = React.useRef(0);
14
14
  const itemRefs = React.useRef([]);
15
15
  const [mounted, setMounted] = React.useState(false);
@@ -34,6 +34,7 @@ const Carousel = (props) => {
34
34
  const el = event.target;
35
35
  const firstVisibleIndex = getFirstVisibleIndex();
36
36
  setScrollPosition(el.scrollLeft);
37
+ onScroll?.(event);
37
38
  if (currentIndexRef.current !== firstVisibleIndex)
38
39
  onChange?.({ index: firstVisibleIndex });
39
40
  currentIndexRef.current = firstVisibleIndex;
@@ -27,6 +27,7 @@ export type Props = {
27
27
  onChange?: (args: {
28
28
  index: number;
29
29
  }) => void;
30
+ onScroll?: (e: React.UIEvent<HTMLUListElement>) => void;
30
31
  className?: G.ClassName;
31
32
  attributes?: G.Attributes<"div">;
32
33
  };
@@ -27,10 +27,10 @@ const ContextMenu = (props) => {
27
27
  React.useEffect(() => {
28
28
  return () => unlockScroll();
29
29
  }, [unlockScroll]);
30
- return (_jsx("div", { className: s.root, ref: originRef, children: _jsx(DropdownMenu, { ...dropdownMenuProps, position: position, originCoordinates: coordinates, active: !!coordinates, onClose: () => {
30
+ return (_jsx("div", { className: s.root, ref: originRef, children: _jsx(DropdownMenu, { ...dropdownMenuProps, position: position, originCoordinates: coordinates, active: !!coordinates, onClose: (args) => {
31
31
  setCoordinates(undefined);
32
32
  unlockScroll();
33
- onClose?.();
33
+ onClose?.(args);
34
34
  } }) }));
35
35
  };
36
36
  ContextMenu.Content = DropdownMenu.Content;
@@ -42,7 +42,7 @@ export const handlers = {
42
42
  await sleep(500);
43
43
  await userEvent.click(root);
44
44
  expect(args.handleClose).toHaveBeenCalledTimes(1);
45
- expect(args.handleClose).toHaveBeenCalledWith();
45
+ expect(args.handleClose).toHaveBeenCalledWith({ reason: "outside-click" });
46
46
  await waitFor(() => {
47
47
  expect(item).not.toBeInTheDocument();
48
48
  expect(scroll).not.toHaveStyle("overflow: hidden");
@@ -40,8 +40,13 @@ const DropdownMenuItem = (props) => {
40
40
  const { onClick } = props;
41
41
  const { handleClose } = useFlyoutContext();
42
42
  const handleClick = (e) => {
43
+ /**
44
+ * Stop event propagation to make sure outside click doesn't get triggered
45
+ * after the content is closed
46
+ */
47
+ e.stopPropagation();
43
48
  if (handleClose)
44
- handleClose({ closeParents: true });
49
+ handleClose({ closeParents: true, reason: "item-selection" });
45
50
  if (onClick)
46
51
  onClick(e);
47
52
  };
@@ -34,7 +34,7 @@ export const defaultActive = {
34
34
  await userEvent.click(document.body);
35
35
  await waitFor(() => {
36
36
  expect(args.handleClose).toHaveBeenCalledTimes(1);
37
- expect(args.handleClose).toHaveBeenCalledWith();
37
+ expect(args.handleClose).toHaveBeenCalledWith({ reason: "outside-click" });
38
38
  expect(item).not.toBeInTheDocument();
39
39
  });
40
40
  await userEvent.click(trigger);
@@ -66,7 +66,7 @@ export const active = {
66
66
  await userEvent.click(document.body);
67
67
  await waitFor(() => {
68
68
  expect(args.handleClose).toHaveBeenCalledTimes(1);
69
- expect(args.handleClose).toHaveBeenCalledWith();
69
+ expect(args.handleClose).toHaveBeenCalledWith({ reason: "outside-click" });
70
70
  });
71
71
  expect(item).toBeInTheDocument();
72
72
  },
@@ -14,7 +14,7 @@ const Popover = (props) => {
14
14
  };
15
15
  const PopoverDismissible = (props) => {
16
16
  const { handleClose } = useFlyoutContext();
17
- return _jsx(Dismissible, { ...props, onClose: handleClose });
17
+ return _jsx(Dismissible, { ...props, onClose: () => handleClose({}) });
18
18
  };
19
19
  Popover.Dismissible = PopoverDismissible;
20
20
  Popover.Trigger = Flyout.Trigger;
@@ -33,7 +33,7 @@ export const defaultActive = {
33
33
  await userEvent.click(document.body);
34
34
  await waitFor(() => {
35
35
  expect(args.handleClose).toHaveBeenCalledTimes(1);
36
- expect(args.handleClose).toHaveBeenCalledWith();
36
+ expect(args.handleClose).toHaveBeenCalledWith({ reason: "outside-click" });
37
37
  expect(item).not.toBeInTheDocument();
38
38
  });
39
39
  await userEvent.click(trigger);
@@ -63,7 +63,7 @@ export const active = {
63
63
  await userEvent.click(document.body);
64
64
  await waitFor(() => {
65
65
  expect(args.handleClose).toHaveBeenCalledTimes(1);
66
- expect(args.handleClose).toHaveBeenCalledWith();
66
+ expect(args.handleClose).toHaveBeenCalledWith({ reason: "outside-click" });
67
67
  });
68
68
  expect(item).toBeInTheDocument();
69
69
  },
@@ -116,7 +116,7 @@ export const dismissible = {
116
116
  await userEvent.click(closeButton);
117
117
  await waitFor(() => {
118
118
  expect(args.handleClose).toHaveBeenCalledTimes(1);
119
- expect(args.handleClose).toHaveBeenCalledWith();
119
+ expect(args.handleClose).toHaveBeenCalledWith({});
120
120
  });
121
121
  },
122
122
  };
@@ -143,7 +143,7 @@ export const triggerType = {
143
143
  await userEvent.unhover(trigger);
144
144
  await waitFor(() => {
145
145
  expect(args.handleClose).toHaveBeenCalledTimes(1);
146
- expect(args.handleClose).toHaveBeenCalledWith();
146
+ expect(args.handleClose).toHaveBeenCalledWith({});
147
147
  });
148
148
  },
149
149
  };
@@ -0,0 +1,3 @@
1
+ import type * as T from "./ProgressIndicator.types";
2
+ declare const ProgressIndicator: (props: T.Props) => import("react/jsx-runtime").JSX.Element;
3
+ export default ProgressIndicator;
@@ -0,0 +1,101 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import React from "react";
4
+ import { classNames } from "../../utilities/helpers.js";
5
+ import { onNextFrame } from "../../utilities/animation.js";
6
+ import usePrevious from "../../hooks/_private/usePrevious.js";
7
+ import s from "./ProgressIndicator.module.css";
8
+ const MAX_RENDERED_ITEMS = 7;
9
+ const BOUNDARY = (MAX_RENDERED_ITEMS - 1) / 2;
10
+ const ProgressIndicator = (props) => {
11
+ const { total, activeIndex = 0, color = "primary", ariaLabel, className, attributes } = props;
12
+ const allItemsVisible = total < MAX_RENDERED_ITEMS;
13
+ const firstRenderedIndex = React.useMemo(() => {
14
+ if (allItemsVisible)
15
+ return 0;
16
+ if (activeIndex <= BOUNDARY)
17
+ return 0;
18
+ if (activeIndex >= total - 1 - BOUNDARY)
19
+ return total - MAX_RENDERED_ITEMS;
20
+ return activeIndex - BOUNDARY;
21
+ }, [activeIndex, allItemsVisible, total]);
22
+ const [startIndex, setStartIndex] = React.useState(firstRenderedIndex);
23
+ const previousActiveIndex = usePrevious(activeIndex);
24
+ const [shift, setShift] = React.useState(null);
25
+ const [animated, setAnimatedState] = React.useState(true);
26
+ const animatedRef = React.useRef(true);
27
+ const rootClassName = classNames(s.root, className, shift && s[`--shift-${shift}`], color && s[`--color-${color}`], animated && s["--animated"]);
28
+ const barAttributes = ariaLabel
29
+ ? {
30
+ "aria-label": ariaLabel,
31
+ role: "progressbar",
32
+ "aria-valuenow": activeIndex,
33
+ "aria-valuemin": 0,
34
+ "aria-valuemax": total - 1,
35
+ }
36
+ : {};
37
+ const setAnimated = (animated) => {
38
+ setAnimatedState(animated);
39
+ animatedRef.current = animated;
40
+ };
41
+ /**
42
+ * After the shift transition, disable the animation and reset the items position
43
+ */
44
+ const handleTransitionEnd = (event) => {
45
+ if (event.target !== event.currentTarget || event.pseudoElement)
46
+ return;
47
+ setAnimated(false);
48
+ };
49
+ React.useEffect(() => {
50
+ if (animated)
51
+ return;
52
+ setShift(null);
53
+ }, [animated]);
54
+ React.useEffect(() => {
55
+ if (shift)
56
+ return;
57
+ onNextFrame(() => setAnimated(true));
58
+ }, [shift, firstRenderedIndex]);
59
+ React.useEffect(() => {
60
+ if (previousActiveIndex === activeIndex)
61
+ return;
62
+ const direction = previousActiveIndex && activeIndex < previousActiveIndex ? "start" : "end";
63
+ const lastIndex = total - 1;
64
+ const endThreshold = lastIndex - BOUNDARY;
65
+ const isAtStartEdge = activeIndex < BOUNDARY || (direction === "end" && activeIndex === BOUNDARY);
66
+ const isAtEndEdge = activeIndex > endThreshold || (direction === "start" && activeIndex === endThreshold);
67
+ const isAtEdge = isAtStartEdge || isAtEndEdge;
68
+ if (allItemsVisible || isAtEdge || !animatedRef.current) {
69
+ setStartIndex(firstRenderedIndex);
70
+ return;
71
+ }
72
+ setStartIndex(firstRenderedIndex);
73
+ setShift(direction);
74
+ }, [activeIndex, firstRenderedIndex, allItemsVisible, previousActiveIndex, total]);
75
+ const renderItems = () => {
76
+ let selectionDelta = 0;
77
+ if (shift === "start")
78
+ selectionDelta = -1;
79
+ if (shift === "end")
80
+ selectionDelta = 1;
81
+ const itemAmount = Math.min(MAX_RENDERED_ITEMS, total);
82
+ const items = [];
83
+ const lastIndex = total - 1;
84
+ const activeVisibleIndex = activeIndex - startIndex + selectionDelta;
85
+ const rightExtra = Math.max(BOUNDARY - activeIndex, 0);
86
+ const leftExtra = Math.max(BOUNDARY - (lastIndex - activeIndex), 0);
87
+ const rightModifierIndex = activeVisibleIndex + rightExtra + 1;
88
+ const leftModifierIndex = activeVisibleIndex - leftExtra - 1;
89
+ for (let i = 0; i < itemAmount; i += 1) {
90
+ const isActive = i === activeVisibleIndex;
91
+ const isSmall = i === rightModifierIndex + 1 || i === leftModifierIndex - 1;
92
+ const isSmaller = i === rightModifierIndex + 2 || i === leftModifierIndex - 2;
93
+ const isHidden = i > rightModifierIndex + 2 || i < leftModifierIndex - 2;
94
+ const itemClassName = classNames(s.item, isActive && s["item--active"], !allItemsVisible && isSmall && s["item--variant-secondary"], !allItemsVisible && isSmaller && s["item--variant-tertiary"], !allItemsVisible && isHidden && s["item--variant-hidden"]);
95
+ items.push(_jsx("div", { className: itemClassName }, i));
96
+ }
97
+ return items;
98
+ };
99
+ return (_jsx("div", { ...attributes, className: rootClassName, children: _jsx("div", { ...barAttributes, className: s.container, onTransitionEnd: handleTransitionEnd, children: renderItems() }) }));
100
+ };
101
+ export default ProgressIndicator;
@@ -0,0 +1 @@
1
+ .root{line-height:0}.container{display:inline-flex;position:relative;vertical-align:top}.container:after,.container:before{content:"";inset-inline-start:calc(var(--rs-unit-x4) * -1);opacity:0;position:absolute}.container:after,.container:before,.item{background:var(--rs-color-background-neutral);border-radius:999px;height:var(--rs-unit-x2);width:var(--rs-unit-x2)}.item{margin-inline-start:var(--rs-unit-x2)}.item:first-child{margin-inline-start:0}.item.item--active{background:var(--rs-color-background-primary);transform:scale(1.2)}.item.item--variant-secondary{opacity:.6}.item.item--variant-tertiary{opacity:.3}.item.item--variant-hidden{opacity:0}.--color-media .container:after,.--color-media .container:before,.--color-media .item{background:var(--rs-color-white)}.--color-media .item{opacity:.6}.--color-media .item.item--active{opacity:1}.--color-media .item.item--variant-secondary{opacity:.3}.--color-media .item.item--variant-tertiary{opacity:.1}.--color-media .item.item--variant-hidden{opacity:0}.--shift-start .container,[dir=rtl] .--shift-end .container{transform:translateX(var(--rs-unit-x4))}.--shift-end .container,[dir=rtl] .--shift-start .container{transform:translateX(calc(var(--rs-unit-x4) * -1))}.--shift-end .container:after,.--shift-start .container:before{opacity:.3}.--shift-end.--color-media .container:after,.--shift-start.--color-media .container:before{opacity:.1}.--shift-start .container:before{inset-inline-end:auto;inset-inline-start:calc(var(--rs-unit-x4) * -1)}.--shift-end .container:after{inset-inline-end:calc(var(--rs-unit-x4) * -1);inset-inline-start:auto}.--animated .container,.--animated .container:after,.--animated .container:before,.--animated .item{transition:var(--rs-duration-slow) var(--rs-easing-decelerate);transition-property:transform,opacity,background-color}
@@ -0,0 +1,9 @@
1
+ import type * as G from "../../types/global";
2
+ export type Props = {
3
+ total: number;
4
+ activeIndex?: number;
5
+ color?: "primary" | "media";
6
+ ariaLabel?: string;
7
+ className?: G.ClassName;
8
+ attributes?: G.Attributes<"div">;
9
+ };
@@ -0,0 +1,2 @@
1
+ export { default } from "./ProgressIndicator";
2
+ export type { Props as ProgressIndicatorProps } from "./ProgressIndicator.types";
@@ -0,0 +1 @@
1
+ export { default } from "./ProgressIndicator.js";
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import { StoryObj } from "@storybook/react";
3
+ declare const _default: {
4
+ title: string;
5
+ component: (props: import("./..").ProgressIndicatorProps) => React.JSX.Element;
6
+ parameters: {
7
+ iframe: {
8
+ url: string;
9
+ };
10
+ };
11
+ };
12
+ export default _default;
13
+ export declare const base: StoryObj;
14
+ export declare const color: {
15
+ name: string;
16
+ render: () => React.JSX.Element;
17
+ };
18
+ export declare const ariaLabel: StoryObj;
19
+ export declare const className: StoryObj;
@@ -0,0 +1,85 @@
1
+ import React from "react";
2
+ import { expect } from "@storybook/test";
3
+ import { Example } from "../../../utilities/storybook/index.js";
4
+ import ProgressIndicator from "../index.js";
5
+ import View from "../../View/index.js";
6
+ import Button from "../../Button/index.js";
7
+ import Text from "../../Text/index.js";
8
+ import Scrim from "../../Scrim/index.js";
9
+ export default {
10
+ title: "Components/ProgressIndicator",
11
+ component: ProgressIndicator,
12
+ parameters: {
13
+ iframe: {
14
+ url: "https://reshaped.so/docs/components/progress-indicator",
15
+ },
16
+ },
17
+ };
18
+ export const base = {
19
+ name: "base",
20
+ render: () => {
21
+ const [activeIndex, setActiveIndex] = React.useState(0);
22
+ const total = 10;
23
+ return (<Example>
24
+ <Example.Item title="base">
25
+ <View gap={4}>
26
+ <View direction="row" gap={2} align="center">
27
+ <Button onClick={() => {
28
+ setActiveIndex((prev) => Math.max(0, prev - 1));
29
+ }}>
30
+ Previous
31
+ </Button>
32
+ <Button onClick={() => {
33
+ setActiveIndex((prev) => Math.min(total - 1, prev + 1));
34
+ }}>
35
+ Next
36
+ </Button>
37
+ <Text weight="medium">Index: {activeIndex}</Text>
38
+ </View>
39
+ <ProgressIndicator total={total} activeIndex={activeIndex}/>
40
+ </View>
41
+ </Example.Item>
42
+ </Example>);
43
+ },
44
+ };
45
+ export const color = {
46
+ name: "color",
47
+ render: () => {
48
+ return (<Example>
49
+ <Example.Item title="color: primary">
50
+ <ProgressIndicator total={10} activeIndex={5} color="primary"/>
51
+ </Example.Item>
52
+ <Example.Item title="color: media">
53
+ <View borderRadius="medium" overflow="hidden" width="300px">
54
+ <Scrim position="bottom" backgroundSlot={<View aspectRatio={16 / 9} backgroundColor="neutral-faded"/>}>
55
+ <View align="center">
56
+ <ProgressIndicator total={10} activeIndex={5} color="media"/>
57
+ </View>
58
+ </Scrim>
59
+ </View>
60
+ </Example.Item>
61
+ </Example>);
62
+ },
63
+ };
64
+ export const ariaLabel = {
65
+ name: "ariaLabel",
66
+ render: () => <ProgressIndicator total={10} className="test-classname" ariaLabel="Progress"/>,
67
+ play: async ({ canvas }) => {
68
+ const progress = canvas.getByRole("progressbar");
69
+ expect(progress).toHaveAttribute("aria-valuenow", "0");
70
+ expect(progress).toHaveAttribute("aria-valuemin", "0");
71
+ expect(progress).toHaveAttribute("aria-valuemax", "9");
72
+ expect(progress).toHaveAccessibleName("Progress");
73
+ },
74
+ };
75
+ export const className = {
76
+ name: "className, attributes",
77
+ render: () => (<div data-testid="root">
78
+ <ProgressIndicator total={10} className="test-classname" attributes={{ id: "test-id" }}/>
79
+ </div>),
80
+ play: async ({ canvas }) => {
81
+ const root = canvas.getByTestId("root").firstChild;
82
+ expect(root).toHaveClass("test-classname");
83
+ expect(root).toHaveAttribute("id", "test-id");
84
+ },
85
+ };
@@ -5,16 +5,15 @@ import { classNames } from "../../utilities/helpers.js";
5
5
  import { GlobalColorMode, PrivateTheme } from "../Theme/index.js";
6
6
  import { ToastProvider } from "../Toast/index.js";
7
7
  import { useGlobalColorMode } from "../Theme/useTheme.js";
8
- import useSingletonKeyboardMode from "../../hooks/_private/useSingletonKeyboardMode.js";
9
- import { SingletonEnvironmentContext, useSingletonRTL, } from "../../hooks/_private/useSingletonEnvironment.js";
8
+ import { SingletonEnvironmentContext, useSingletonEnvironment, } from "../../hooks/_private/useSingletonEnvironment.js";
9
+ import { SingletonKeyboardModeProvider } from "../../hooks/_private/useSingletonKeyboardMode.js";
10
10
  import { SingletonHotkeysProvider } from "../../hooks/_private/useSingletonHotkeys.js";
11
11
  import "./Reshaped.css";
12
12
  import s from "./Reshaped.module.css";
13
13
  const ReshapedInner = (props) => {
14
14
  const { children, defaultRTL, defaultViewport = "s", toastOptions } = props;
15
- const rtlState = useSingletonRTL(defaultRTL);
16
- useSingletonKeyboardMode();
17
- return (_jsx(SingletonEnvironmentContext.Provider, { value: { rtl: rtlState, defaultViewport }, children: _jsx(SingletonHotkeysProvider, { children: _jsx(ToastProvider, { options: toastOptions, children: children }) }) }));
15
+ const rtlState = useSingletonEnvironment(defaultRTL);
16
+ return (_jsx(SingletonKeyboardModeProvider, { children: _jsx(SingletonEnvironmentContext.Provider, { value: { rtl: rtlState, defaultViewport }, children: _jsx(SingletonHotkeysProvider, { children: _jsx(ToastProvider, { options: toastOptions, children: children }) }) }) }));
18
17
  };
19
18
  const Reshaped = (props) => {
20
19
  const { theme, defaultTheme = "reshaped", defaultColorMode, scoped, className } = props;
@@ -1 +1 @@
1
- .root{--rs-p-h:var(--rs-text-field-gap);align-items:center;background:var(--rs-color-background-elevation-base);border:1px solid var(--rs-color-border-neutral);display:flex;gap:var(--rs-text-field-gap);padding:calc(var(--rs-unit-x1) - 1px) calc(var(--rs-text-field-gap) - 1px);position:relative;row-gap:var(--rs-unit-x1);z-index:0}.root:has(label:active),.root:not(:has(button:focus,a:focus,[tabindex="0"]:focus)):focus-within{border-color:var(--rs-color-border-primary);box-shadow:0 0 0 1px var(--rs-color-border-primary)}.root.--multiline{flex-wrap:wrap}.root.--multiline .input{width:auto}.root.--rounded{border-radius:999px}.root.--rounded .affix:first-child,.root.--rounded .icon:first-child{padding-inline-start:var(--rs-unit-x1)}.root.--rounded .input:first-child{padding-inline-start:calc(var(--rs-text-field-gap) + var(--rs-unit-x1))}.input{background:none;border:none;box-sizing:border-box;color:var(--rs-color-foreground-neutral);flex-grow:1;font-family:var(--rs-font-family-body);font-weight:var(--rs-font-weight-regular);margin:calc(var(--rs-unit-x1) * -1) calc(var(--rs-text-field-gap) * -1);outline:none;padding-inline:var(--rs-text-field-gap);position:relative;width:100%;z-index:1}.input:-webkit-autofill{-webkit-background-clip:text;-webkit-text-fill-color:var(--rs-color-foreground-neutral)}.affix,.icon{cursor:text}.affix,.icon,.slot{align-items:center;display:flex;flex-shrink:0;min-height:calc(var(--rs-text-field-line-height) + var(--rs-unit-x1) * 2);position:relative;z-index:5}.slot--position-end:last-child{margin-inline-end:calc(var(--rs-unit-x1) * -1)}.affix{color:var(--rs-color-foreground-neutral-faded)}.affix.affix--position-start{padding-inline-end:var(--rs-text-field-gap)}.affix.affix--position-start:after{border-inline-end:1px solid var(--rs-color-border-neutral-faded);content:"";inset-block:var(--rs-unit-x1);inset-inline-end:0;position:absolute}.affix.affix--position-end{padding-inline-start:var(--rs-text-field-gap)}.affix.affix--position-end:after{border-inline-start:1px solid var(--rs-color-border-neutral-faded);content:"";inset-block:var(--rs-unit-x1);inset-inline-start:0;position:absolute}.root.--disabled{background:var(--rs-color-background-disabled-faded);border-color:var(--rs-color-border-disabled)}.root.--disabled,.root.--disabled .input{color:var(--rs-color-foreground-disabled);cursor:not-allowed}.--size-medium{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium .input{padding-block:var(--rs-unit-x2)}.--size-medium .affix,.--size-medium .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large .input{padding-block:var(--rs-unit-x3)}.--size-large .affix,.--size-large .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge .input{padding-block:var(--rs-unit-x4)}.--size-xlarge .affix,.--size-xlarge .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.root.--variant-faded{background:var(--rs-color-background-neutral-faded);border-color:transparent}.root.--variant-faded:focus-within{border-color:var(--rs-color-border-primary)}.root.--variant-headless{background:transparent;border-color:transparent}.root.--variant-headless.--status-error,.root.--variant-headless.--status-error:focus-within,.root.--variant-headless:focus-within{border-color:transparent;box-shadow:none}.root.--status-error{border-color:var(--rs-color-border-critical)}.root.--status-error:focus-within{border-color:var(--rs-color-border-primary)}@media (--rs-viewport-s ) and (hover:none){.input{font-size:var(--rs-font-size-body-2)!important}}@media (--rs-viewport-m ){.--size-medium--m{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium--m .input{padding-block:var(--rs-unit-x2)}.--size-medium--m .affix,.--size-medium--m .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large--m{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large--m .input{padding-block:var(--rs-unit-x3)}.--size-large--m .affix,.--size-large--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge--m{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge--m .input{padding-block:var(--rs-unit-x4)}.--size-xlarge--m .affix,.--size-xlarge--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}@media (--rs-viewport-l ){.--size-medium--l{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium--l .input{padding-block:var(--rs-unit-x2)}.--size-medium--l .affix,.--size-medium--l .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large--l{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large--l .input{padding-block:var(--rs-unit-x3)}.--size-large--l .affix,.--size-large--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge--l{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge--l .input{padding-block:var(--rs-unit-x4)}.--size-xlarge--l .affix,.--size-xlarge--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}@media (--rs-viewport-xl ){.--size-medium--xl{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium--xl .input{padding-block:var(--rs-unit-x2)}.--size-medium--xl .affix,.--size-medium--xl .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large--xl{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large--xl .input{padding-block:var(--rs-unit-x3)}.--size-large--xl .affix,.--size-large--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge--xl{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge--xl .input{padding-block:var(--rs-unit-x4)}.--size-xlarge--xl .affix,.--size-xlarge--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}
1
+ .root{--rs-p-h:var(--rs-text-field-gap);align-items:center;background:var(--rs-color-background-elevation-base);border:1px solid var(--rs-color-border-neutral);display:flex;gap:var(--rs-text-field-gap);padding:calc(var(--rs-unit-x1) - 1px) calc(var(--rs-text-field-gap) - 1px);position:relative;row-gap:var(--rs-unit-x1);z-index:0}.root.--focused,.root:has(label:active),.root:not(:has(button:focus,a:focus,[tabindex="0"]:focus)):focus-within{border-color:var(--rs-color-border-primary);box-shadow:0 0 0 1px var(--rs-color-border-primary)}.root.--multiline{flex-wrap:wrap}.root.--multiline .input{width:auto}.root.--rounded{border-radius:999px}.root.--rounded .affix:first-child,.root.--rounded .icon:first-child{padding-inline-start:var(--rs-unit-x1)}.root.--rounded .input:first-child{padding-inline-start:calc(var(--rs-text-field-gap) + var(--rs-unit-x1))}.input{background:none;border:none;box-sizing:border-box;color:var(--rs-color-foreground-neutral);flex-grow:1;font-family:var(--rs-font-family-body);font-weight:var(--rs-font-weight-regular);margin:calc(var(--rs-unit-x1) * -1) calc(var(--rs-text-field-gap) * -1);outline:none;padding-inline:var(--rs-text-field-gap);position:relative;width:100%;z-index:1}.input:-webkit-autofill{-webkit-background-clip:text;-webkit-text-fill-color:var(--rs-color-foreground-neutral)}.affix,.icon{cursor:text}.affix,.icon,.slot{align-items:center;display:flex;flex-shrink:0;min-height:calc(var(--rs-text-field-line-height) + var(--rs-unit-x1) * 2);position:relative;z-index:5}.slot--position-end:last-child{margin-inline-end:calc(var(--rs-unit-x1) * -1)}.affix{color:var(--rs-color-foreground-neutral-faded)}.affix.affix--position-start{padding-inline-end:var(--rs-text-field-gap)}.affix.affix--position-start:after{border-inline-end:1px solid var(--rs-color-border-neutral-faded);content:"";inset-block:var(--rs-unit-x1);inset-inline-end:0;position:absolute}.affix.affix--position-end{padding-inline-start:var(--rs-text-field-gap)}.affix.affix--position-end:after{border-inline-start:1px solid var(--rs-color-border-neutral-faded);content:"";inset-block:var(--rs-unit-x1);inset-inline-start:0;position:absolute}.root.--disabled{background:var(--rs-color-background-disabled-faded);border-color:var(--rs-color-border-disabled)}.root.--disabled,.root.--disabled .input{color:var(--rs-color-foreground-disabled);cursor:not-allowed}.--size-medium{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium .input{padding-block:var(--rs-unit-x2)}.--size-medium .affix,.--size-medium .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large .input{padding-block:var(--rs-unit-x3)}.--size-large .affix,.--size-large .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge .input{padding-block:var(--rs-unit-x4)}.--size-xlarge .affix,.--size-xlarge .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.root.--variant-faded{background:var(--rs-color-background-neutral-faded);border-color:transparent}.root.--variant-faded.--focused,.root.--variant-faded:focus-within{border-color:var(--rs-color-border-primary)}.root.--variant-headless{background:transparent;border-color:transparent}.root.--variant-headless.--status-error,.root.--variant-headless.--status-error.--focused,.root.--variant-headless.--status-error:focus-within,.root.--variant-headless:focus-within{border-color:transparent;box-shadow:none}.root.--status-error{border-color:var(--rs-color-border-critical)}.root.--status-error.--focused,.root.--status-error:focus-within{border-color:var(--rs-color-border-primary)}@media (--rs-viewport-s ) and (hover:none){.input{font-size:var(--rs-font-size-body-2)!important}}@media (--rs-viewport-m ){.--size-medium--m{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium--m .input{padding-block:var(--rs-unit-x2)}.--size-medium--m .affix,.--size-medium--m .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large--m{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large--m .input{padding-block:var(--rs-unit-x3)}.--size-large--m .affix,.--size-large--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge--m{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge--m .input{padding-block:var(--rs-unit-x4)}.--size-xlarge--m .affix,.--size-xlarge--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}@media (--rs-viewport-l ){.--size-medium--l{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium--l .input{padding-block:var(--rs-unit-x2)}.--size-medium--l .affix,.--size-medium--l .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large--l{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large--l .input{padding-block:var(--rs-unit-x3)}.--size-large--l .affix,.--size-large--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge--l{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge--l .input{padding-block:var(--rs-unit-x4)}.--size-xlarge--l .affix,.--size-xlarge--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}@media (--rs-viewport-xl ){.--size-medium--xl{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium--xl .input{padding-block:var(--rs-unit-x2)}.--size-medium--xl .affix,.--size-medium--xl .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large--xl{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large--xl .input{padding-block:var(--rs-unit-x3)}.--size-large--xl .affix,.--size-large--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge--xl{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge--xl .input{padding-block:var(--rs-unit-x4)}.--size-xlarge--xl .affix,.--size-xlarge--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}
@@ -145,7 +145,10 @@ const Color = () => {
145
145
  color: "inverted",
146
146
  title: "Hey!",
147
147
  icon: IconZap,
148
- actionsSlot: [<Button onClick={() => toast.hide(id)}>Close</Button>],
148
+ actionsSlot: [
149
+ <Button onClick={() => toast.hide(id)}>Undo</Button>,
150
+ <Button onClick={() => toast.hide(id)}>Hide</Button>,
151
+ ],
149
152
  });
150
153
  }}>
151
154
  Show toast
@@ -158,7 +161,10 @@ const Color = () => {
158
161
  color: "neutral",
159
162
  title: "Hey!",
160
163
  icon: IconZap,
161
- actionsSlot: [<Button onClick={() => toast.hide(id)}>Close</Button>],
164
+ actionsSlot: [
165
+ <Button onClick={() => toast.hide(id)}>Undo</Button>,
166
+ <Button onClick={() => toast.hide(id)}>Hide</Button>,
167
+ ],
162
168
  });
163
169
  }}>
164
170
  Show toast
@@ -171,7 +177,10 @@ const Color = () => {
171
177
  color: "primary",
172
178
  title: "Hey!",
173
179
  icon: IconZap,
174
- actionsSlot: [<Button onClick={() => toast.hide(id)}>Close</Button>],
180
+ actionsSlot: [
181
+ <Button onClick={() => toast.hide(id)}>Undo</Button>,
182
+ <Button onClick={() => toast.hide(id)}>Hide</Button>,
183
+ ],
175
184
  });
176
185
  }}>
177
186
  Show toast
@@ -184,7 +193,10 @@ const Color = () => {
184
193
  color: "positive",
185
194
  title: "Hey!",
186
195
  icon: IconZap,
187
- actionsSlot: [<Button onClick={() => toast.hide(id)}>Close</Button>],
196
+ actionsSlot: [
197
+ <Button onClick={() => toast.hide(id)}>Undo</Button>,
198
+ <Button onClick={() => toast.hide(id)}>Hide</Button>,
199
+ ],
188
200
  });
189
201
  }}>
190
202
  Show toast
@@ -197,7 +209,10 @@ const Color = () => {
197
209
  color: "critical",
198
210
  title: "Hey!",
199
211
  icon: IconZap,
200
- actionsSlot: [<Button onClick={() => toast.hide(id)}>Close</Button>],
212
+ actionsSlot: [
213
+ <Button onClick={() => toast.hide(id)}>Undo</Button>,
214
+ <Button onClick={() => toast.hide(id)}>Hide</Button>,
215
+ ],
201
216
  });
202
217
  }}>
203
218
  Show toast
@@ -211,8 +226,8 @@ const Color = () => {
211
226
  title: "Hey!",
212
227
  icon: IconZap,
213
228
  actionsSlot: [
214
- <Button onClick={() => toast.hide(id)}>Close</Button>,
215
- <Button onClick={() => toast.hide(id)}>Close</Button>,
229
+ <Button onClick={() => toast.hide(id)}>Undo</Button>,
230
+ <Button onClick={() => toast.hide(id)}>Hide</Button>,
216
231
  ],
217
232
  });
218
233
  }}>
@@ -33,7 +33,7 @@ export const defaultActive = {
33
33
  await userEvent.unhover(trigger);
34
34
  await waitFor(() => {
35
35
  expect(args.handleClose).toHaveBeenCalledTimes(1);
36
- expect(args.handleClose).toHaveBeenCalledWith();
36
+ expect(args.handleClose).toHaveBeenCalledWith({});
37
37
  expect(item).not.toBeInTheDocument();
38
38
  });
39
39
  },