reshaped 3.1.2 → 3.1.4

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 (94) hide show
  1. package/CHANGELOG.md +26 -2
  2. package/dist/bundle.css +1 -1
  3. package/dist/bundle.d.ts +1 -1
  4. package/dist/bundle.js +11 -11
  5. package/dist/cjs/config/tailwind.js +5 -9
  6. package/dist/cjs/themes/_generator/tokens/font/font.transforms.js +1 -1
  7. package/dist/cjs/themes/_generator/utilities/generateColors.js +2 -2
  8. package/dist/cjs/themes/figma/theme.css +1 -1
  9. package/dist/cjs/themes/reshaped/theme.css +1 -1
  10. package/dist/cjs/themes/slate/theme.css +1 -1
  11. package/dist/components/Accordion/tests/Accordion.stories.js +33 -19
  12. package/dist/components/Actionable/Actionable.js +3 -1
  13. package/dist/components/Autocomplete/Autocomplete.js +22 -18
  14. package/dist/components/Autocomplete/Autocomplete.types.d.ts +4 -2
  15. package/dist/components/Autocomplete/index.d.ts +1 -1
  16. package/dist/components/Autocomplete/tests/Autocomplete.stories.d.ts +1 -0
  17. package/dist/components/Autocomplete/tests/Autocomplete.stories.js +81 -0
  18. package/dist/components/Badge/Badge.module.css +1 -1
  19. package/dist/components/Badge/Badge.types.d.ts +1 -1
  20. package/dist/components/Button/tests/Button.stories.js +1 -1
  21. package/dist/components/Dismissible/Dismissible.module.css +1 -1
  22. package/dist/components/FileUpload/FileUpload.js +8 -2
  23. package/dist/components/FileUpload/FileUpload.types.d.ts +2 -0
  24. package/dist/components/FileUpload/tests/FileUpload.stories.d.ts +1 -0
  25. package/dist/components/FileUpload/tests/FileUpload.stories.js +10 -0
  26. package/dist/components/Image/Image.js +3 -1
  27. package/dist/components/Loader/tests/Loader.stories.js +1 -1
  28. package/dist/components/Modal/Modal.js +3 -3
  29. package/dist/components/Modal/Modal.module.css +1 -1
  30. package/dist/components/Modal/Modal.types.d.ts +7 -3
  31. package/dist/components/Modal/tests/Modal.stories.d.ts +1 -0
  32. package/dist/components/Modal/tests/Modal.stories.js +27 -0
  33. package/dist/components/Overlay/Overlay.js +5 -5
  34. package/dist/components/Overlay/Overlay.module.css +1 -1
  35. package/dist/components/Overlay/Overlay.types.d.ts +4 -1
  36. package/dist/components/Overlay/index.d.ts +1 -1
  37. package/dist/components/Pagination/PaginationControlled.js +3 -2
  38. package/dist/components/Pagination/tests/Pagination.stories.js +3 -0
  39. package/dist/components/Reshaped/Reshaped.css +1 -1
  40. package/dist/components/Reshaped/Reshaped.js +3 -3
  41. package/dist/components/Reshaped/Reshaped.module.css +1 -1
  42. package/dist/components/Reshaped/Reshaped.types.d.ts +4 -3
  43. package/dist/components/Switch/Switch.js +1 -1
  44. package/dist/components/Switch/tests/Switch.stories.js +5 -0
  45. package/dist/components/Table/Table.module.css +1 -1
  46. package/dist/components/Text/Text.js +3 -1
  47. package/dist/components/Text/Text.module.css +1 -1
  48. package/dist/components/TextField/TextField.js +5 -6
  49. package/dist/components/TextField/TextField.module.css +1 -1
  50. package/dist/components/TextField/TextField.types.d.ts +2 -0
  51. package/dist/components/TextField/tests/TextField.stories.d.ts +1 -1
  52. package/dist/components/TextField/tests/TextField.stories.js +6 -2
  53. package/dist/components/Theme/GlobalColorMode.js +3 -2
  54. package/dist/components/Theme/Theme.d.ts +1 -0
  55. package/dist/components/Theme/Theme.js +13 -12
  56. package/dist/components/Theme/Theme.types.d.ts +4 -0
  57. package/dist/components/Theme/Theme.utilities.d.ts +1 -0
  58. package/dist/components/Theme/Theme.utilities.js +1 -0
  59. package/dist/components/Theme/index.d.ts +1 -1
  60. package/dist/components/Theme/index.js +1 -1
  61. package/dist/components/Toast/Toast.types.d.ts +1 -1
  62. package/dist/components/Toast/tests/Toast.stories.js +16 -0
  63. package/dist/components/Tooltip/Tooltip.js +2 -2
  64. package/dist/components/Tooltip/Tooltip.types.d.ts +1 -1
  65. package/dist/components/View/View.js +3 -1
  66. package/dist/components/View/View.types.d.ts +1 -1
  67. package/dist/components/View/tests/View.stories.js +4 -0
  68. package/dist/components/_private/Aligner/Aligner.module.css +1 -1
  69. package/dist/components/_private/Flyout/Flyout.types.d.ts +2 -0
  70. package/dist/components/_private/Flyout/FlyoutControlled.js +16 -9
  71. package/dist/components/_private/Flyout/FlyoutTrigger.js +2 -1
  72. package/dist/components/_private/Flyout/tests/Flyout.stories.js +6 -0
  73. package/dist/components/_private/Flyout/useFlyout.d.ts +5 -1
  74. package/dist/components/_private/Flyout/useFlyout.js +20 -6
  75. package/dist/components/_private/Portal/Portal.types.d.ts +2 -2
  76. package/dist/config/tailwind.js +5 -9
  77. package/dist/constants/keys.d.ts +1 -0
  78. package/dist/constants/keys.js +1 -0
  79. package/dist/hooks/_private/useSingletonHotkeys.d.ts +3 -3
  80. package/dist/hooks/useDrag.d.ts +1 -1
  81. package/dist/hooks/useResponsiveClientValue.js +3 -3
  82. package/dist/icons/Plus.d.ts +2 -0
  83. package/dist/icons/Plus.js +3 -0
  84. package/dist/index.d.ts +1 -1
  85. package/dist/styles/textAlign/index.d.ts +3 -0
  86. package/dist/styles/textAlign/index.js +10 -0
  87. package/dist/styles/textAlign/textAlign.module.css +1 -0
  88. package/dist/styles/types.d.ts +1 -0
  89. package/dist/themes/_generator/tokens/font/font.transforms.js +1 -1
  90. package/dist/themes/_generator/utilities/generateColors.js +2 -2
  91. package/dist/themes/figma/theme.css +1 -1
  92. package/dist/themes/reshaped/theme.css +1 -1
  93. package/dist/themes/slate/theme.css +1 -1
  94. package/package.json +3 -2
@@ -4,10 +4,12 @@ import React from "react";
4
4
  import { classNames } from "../../utilities/helpers.js";
5
5
  import useIsomorphicLayoutEffect from "../../hooks/useIsomorphicLayoutEffect.js";
6
6
  import { ThemeContext } from "./Theme.context.js";
7
+ import { getRootThemeEl } from "./Theme.utilities.js";
7
8
  import { useTheme, useGlobalColorMode } from "./useTheme.js";
8
9
  import s from "./Theme.module.css";
9
- const Theme = (props) => {
10
- const { name, defaultName, colorMode, children, className } = props;
10
+ const Theme = (props) => _jsx(PrivateTheme, { ...props });
11
+ export const PrivateTheme = (props) => {
12
+ const { name, defaultName, colorMode, scoped, children, className } = props;
11
13
  const [mounted, setMounted] = React.useState(false);
12
14
  const [stateTheme, setStateTheme] = React.useState(defaultName);
13
15
  const globalColorMode = useGlobalColorMode();
@@ -36,16 +38,15 @@ const Theme = (props) => {
36
38
  useIsomorphicLayoutEffect(() => {
37
39
  if (!document || !isRootProvider)
38
40
  return;
39
- const hasColorModeApplied = document.documentElement.getAttribute("data-rs-color-mode");
40
- document.documentElement.setAttribute("data-rs-theme", usedTheme);
41
- if (!hasColorModeApplied) {
42
- document.documentElement.setAttribute("data-rs-color-mode", usedColorMode);
43
- }
41
+ const themeRootEl = getRootThemeEl();
42
+ const hasColorModeApplied = themeRootEl.getAttribute("data-rs-color-mode");
43
+ themeRootEl.setAttribute("data-rs-theme", usedTheme);
44
+ if (!hasColorModeApplied)
45
+ themeRootEl.setAttribute("data-rs-color-mode", usedColorMode);
44
46
  return () => {
45
- document.documentElement.removeAttribute("data-rs-theme");
46
- if (!hasColorModeApplied) {
47
- document.documentElement.removeAttribute("data-rs-color-mode");
48
- }
47
+ themeRootEl.removeAttribute("data-rs-theme");
48
+ if (!hasColorModeApplied)
49
+ themeRootEl.removeAttribute("data-rs-color-mode");
49
50
  };
50
51
  }, [usedTheme, usedColorMode, isRootProvider]);
51
52
  const value = React.useMemo(() => ({
@@ -55,6 +56,6 @@ const Theme = (props) => {
55
56
  setTheme,
56
57
  setRootTheme,
57
58
  }), [usedTheme, usedColorMode, setTheme, setRootTheme, rootTheme]);
58
- return (_jsx(ThemeContext.Provider, { value: value, children: _jsx("div", { className: rootClassNames, "data-rs-theme": isRootProvider ? undefined : usedTheme, "data-rs-color-mode": isRootProvider || (!colorMode && !mounted) ? undefined : usedColorMode, children: children }) }));
59
+ return (_jsx(ThemeContext.Provider, { value: value, children: _jsx("div", { className: rootClassNames, "data-rs-root": scoped ? true : undefined, "data-rs-theme": isRootProvider ? undefined : usedTheme, "data-rs-color-mode": isRootProvider || (!colorMode && !mounted) ? undefined : usedColorMode, children: children }) }));
59
60
  };
60
61
  export default Theme;
@@ -20,7 +20,11 @@ export type Props = {
20
20
  className?: G.ClassName;
21
21
  children?: React.ReactNode;
22
22
  };
23
+ export type PrivateProps = Props & {
24
+ scoped?: boolean;
25
+ };
23
26
  export type GlobalColorModeProps = {
24
27
  defaultMode?: ColorMode;
28
+ scoped?: boolean;
25
29
  children?: React.ReactNode;
26
30
  };
@@ -0,0 +1 @@
1
+ export declare const getRootThemeEl: () => Element;
@@ -0,0 +1 @@
1
+ export const getRootThemeEl = () => document.querySelector("[data-rs-root]") || document.documentElement;
@@ -1,4 +1,4 @@
1
- export { default } from "./Theme";
1
+ export { default, PrivateTheme } from "./Theme";
2
2
  export { default as GlobalColorMode } from "./GlobalColorMode";
3
3
  export { useTheme } from "./useTheme";
4
4
  export type { Props as ThemeProps, GlobalColorModeProps } from "./Theme.types";
@@ -1,3 +1,3 @@
1
- export { default } from "./Theme.js";
1
+ export { default, PrivateTheme } from "./Theme.js";
2
2
  export { default as GlobalColorMode } from "./GlobalColorMode.js";
3
3
  export { useTheme } from "./useTheme.js";
@@ -13,7 +13,7 @@ export type Props = {
13
13
  text?: React.ReactNode;
14
14
  children?: React.ReactNode;
15
15
  actionsSlot?: React.ReactNode;
16
- color?: "neutral" | "primary" | "critical" | "positive" | "inverted";
16
+ color?: "neutral" | "primary" | "critical" | "positive" | "warning" | "inverted";
17
17
  className?: G.ClassName;
18
18
  attributes?: G.Attributes<"div">;
19
19
  };
@@ -199,6 +199,22 @@ const Color = () => {
199
199
  icon: IconZap,
200
200
  actionsSlot: [<Button onClick={() => toast.hide(id)}>Close</Button>],
201
201
  });
202
+ }}>
203
+ Show toast
204
+ </Button>
205
+ </Example.Item>
206
+ <Example.Item title="color: warning">
207
+ <Button onClick={() => {
208
+ const id = toast.show({
209
+ text: "Event completed",
210
+ color: "warning",
211
+ title: "Hey!",
212
+ icon: IconZap,
213
+ actionsSlot: [
214
+ <Button onClick={() => toast.hide(id)}>Close</Button>,
215
+ <Button onClick={() => toast.hide(id)}>Close</Button>,
216
+ ],
217
+ });
202
218
  }}>
203
219
  Show toast
204
220
  </Button>
@@ -5,9 +5,9 @@ import Text from "../Text/index.js";
5
5
  import Flyout from "../_private/Flyout/index.js";
6
6
  import s from "./Tooltip.module.css";
7
7
  const Tooltip = (props) => {
8
- const { id, text, children, onOpen, onClose, position = "bottom", active, disabled, disableContentHover, } = props;
8
+ const { id, text, children, onOpen, onClose, position = "bottom", containerRef, active, disabled, disableContentHover, } = props;
9
9
  if (!text)
10
10
  return _jsx(_Fragment, { children: children({}) });
11
- return (_jsxs(Flyout, { id: id, active: active, position: position, disabled: disabled, onOpen: onOpen, onClose: onClose, disableContentHover: disableContentHover, triggerType: "hover", children: [_jsx(Flyout.Trigger, { children: children }), _jsx(Flyout.Content, { children: _jsx(Theme, { colorMode: "inverted", children: _jsx(Text, { variant: "caption-1", className: s.root, children: text }) }) })] }));
11
+ return (_jsxs(Flyout, { id: id, active: active, position: position, disabled: disabled, onOpen: onOpen, onClose: onClose, disableContentHover: disableContentHover, containerRef: containerRef, triggerType: "hover", children: [_jsx(Flyout.Trigger, { children: children }), _jsx(Flyout.Content, { children: _jsx(Theme, { colorMode: "inverted", children: _jsx(Text, { variant: "caption-1", className: s.root, children: text }) }) })] }));
12
12
  };
13
13
  export default Tooltip;
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import type { FlyoutProps, FlyoutTriggerProps } from "../_private/Flyout";
3
- export type Props = Pick<FlyoutProps, "id" | "position" | "onOpen" | "onClose" | "active" | "disabled" | "disableContentHover"> & {
3
+ export type Props = Pick<FlyoutProps, "id" | "position" | "onOpen" | "onClose" | "active" | "disabled" | "disableContentHover" | "containerRef"> & {
4
4
  children: (attributes: Parameters<FlyoutTriggerProps["children"]>[0] | {}) => React.ReactNode;
5
5
  text?: React.ReactNode;
6
6
  };
@@ -17,6 +17,7 @@ import getPositionStyles from "../../styles/position/index.js";
17
17
  import getInsetStyles from "../../styles/inset/index.js";
18
18
  import getAspectRatioStyles from "../../styles/aspectRatio/index.js";
19
19
  import getBorderStyles from "../../styles/border/index.js";
20
+ import getTextAlignStyles from "../../styles/textAlign/index.js";
20
21
  const ViewItem = (props) => {
21
22
  const { columns, grow, gapBefore, as: TagName = "div", order, children, className, attributes, } = props;
22
23
  const itemClassNames = classNames(s.item, className, gapBefore === "auto" && s["item--gap-auto"], gapBefore !== undefined && s["item--gap-before"], columns && s["item--columns"], ...responsiveClassNames(s, "item--grow", grow), ...responsiveClassNames(s, "item--columns", columns));
@@ -63,6 +64,7 @@ const View = (props) => {
63
64
  const insetEndStyles = getInsetStyles(insetEnd, "end");
64
65
  const aspectRatioStyles = getAspectRatioStyles(aspectRatio);
65
66
  const borderStyles = getBorderStyles(borderColor);
67
+ const textAlignStyles = getTextAlignStyles(textAlign);
66
68
  let renderedItemIndex = 0;
67
69
  // If wrap is not defined, it can be set based on item grow and split usage
68
70
  let nowrap;
@@ -135,7 +137,7 @@ const View = (props) => {
135
137
  return renderItem({ child, index: renderedIndex });
136
138
  });
137
139
  // Classnames and attributes are written here so we can assign nowrap to the root element based on the children
138
- const rootClassNames = classNames(s.root, className, radiusStyles?.classNames, positionStyles?.classNames, bleedStyles?.classNames, widthStyles?.classNames, heightStyles?.classNames, aspectRatioStyles?.classNames, maxWidthStyles?.classNames, maxHeightStyles?.classNames, minWidthStyles?.classNames, minHeightStyles?.classNames, insetStyles?.classNames, insetTopStyles?.classNames, insetBottomStyles?.classNames, insetStartStyles?.classNames, insetEndStyles?.classNames, borderStyles?.classNames, textAlign && s[`--align-text-${textAlign}`], backgroundColor && s[`--bg-${backgroundColor}`], shadow && s[`--shadow-${shadow}`], overflow && s[`--overflow-${overflow}`], animated && s["--animated"], divided && s["--divided"], (padding !== undefined || paddingInline !== undefined || paddingBlock !== undefined) &&
140
+ const rootClassNames = classNames(s.root, className, radiusStyles?.classNames, positionStyles?.classNames, bleedStyles?.classNames, widthStyles?.classNames, heightStyles?.classNames, aspectRatioStyles?.classNames, maxWidthStyles?.classNames, maxHeightStyles?.classNames, minWidthStyles?.classNames, minHeightStyles?.classNames, insetStyles?.classNames, insetTopStyles?.classNames, insetBottomStyles?.classNames, insetStartStyles?.classNames, insetEndStyles?.classNames, borderStyles?.classNames, textAlignStyles?.classNames, backgroundColor && s[`--bg-${backgroundColor}`], shadow && s[`--shadow-${shadow}`], overflow && s[`--overflow-${overflow}`], animated && s["--animated"], divided && s["--divided"], (padding !== undefined || paddingInline !== undefined || paddingBlock !== undefined) &&
139
141
  s["--padding"], paddingBottom !== undefined && s["--padding-bottom"], paddingEnd !== undefined && s["--padding-end"], paddingStart !== undefined && s["--padding-start"], paddingTop !== undefined && s["--padding-top"], (isFlex || nowrap) && s["--flex"], ...responsiveClassNames(s, "--direction", direction), ...responsiveClassNames(s, "--align", align), ...responsiveClassNames(s, "--justify", justify),
140
142
  // Wrap and nowrap are separate here because inverting any of them could result into a false value which will be ignored by classNames
141
143
  ...responsiveClassNames(s, "--nowrap", nowrap || wrap === false), ...responsiveClassNames(s, "--wrap", wrap),
@@ -27,7 +27,7 @@ export type Props<TagName extends keyof JSX.IntrinsicElements = "div"> = {
27
27
  paddingInline?: G.Responsive<number>;
28
28
  paddingBlock?: G.Responsive<number>;
29
29
  bleed?: G.Responsive<number>;
30
- textAlign?: "center" | "start" | "end";
30
+ textAlign?: G.Responsive<TStyles.TextAlign>;
31
31
  backgroundColor?: "neutral" | "neutral-faded" | "critical" | "critical-faded" | "positive" | "warning" | "warning-faded" | "positive-faded" | "primary" | "primary-faded" | "elevation-base" | "elevation-raised" | "elevation-overlay" | "page" | "page-faded" | "disabled" | "disabled-faded" | "brand" | "white" | "black";
32
32
  borderColor?: G.Responsive<TStyles.BorderColor>;
33
33
  borderRadius?: G.Responsive<TStyles.Radius>;
@@ -359,6 +359,10 @@ export const textAlign = () => (<Example>
359
359
  <Example.Item title="textAlign: end">
360
360
  <View textAlign="end">Content</View>
361
361
  </Example.Item>
362
+
363
+ <Example.Item title="textAlign: [s] start, [m+] end">
364
+ <View textAlign={{ s: "start", m: "end" }}>Content</View>
365
+ </Example.Item>
362
366
  </Example>);
363
367
  export const size = () => (<Example>
364
368
  <Example.Item title="height: 100px, width: 100px">
@@ -1 +1 @@
1
- .root [data-rs-aligner-target]{--rs-aligner-p-h:var(--rs-p-h,var(--rs-p));--rs-aligner-p-v:var(--rs-p-v,var(--rs-p))}.root.--side-all [data-rs-aligner-target]{margin:calc(var(--rs-aligner-p-v) * -1) calc(var(--rs-aligner-p-h) * -1)}.root.--side-inline [data-rs-aligner-target],.root.--side-start [data-rs-aligner-target]{margin-inline-start:calc(var(--rs-aligner-p-h) * -1)}.root.--side-end [data-rs-aligner-target],.root.--side-inline [data-rs-aligner-target]{margin-inline-end:calc(var(--rs-aligner-p-h) * -1)}.root.--side-block [data-rs-aligner-target],.root.--side-top [data-rs-aligner-target]{margin-block-start:calc(var(--rs-aligner-p-v) * -1)}.root.--side-block [data-rs-aligner-target],.root.--side-bottom [data-rs-aligner-target]{margin-block-end:calc(var(--rs-aligner-p-v) * -1)}
1
+ .root [data-rs-aligner-target]{--rs-aligner-p-h:var(--rs-p-h,var(--rs-p,0px));--rs-aligner-p-v:var(--rs-p-v,var(--rs-p,0px))}.root.--side-all [data-rs-aligner-target]{margin:calc(var(--rs-aligner-p-v) * -1) calc(var(--rs-aligner-p-h) * -1)}.root.--side-inline [data-rs-aligner-target],.root.--side-start [data-rs-aligner-target]{margin-inline-start:calc(var(--rs-aligner-p-h) * -1)}.root.--side-end [data-rs-aligner-target],.root.--side-inline [data-rs-aligner-target]{margin-inline-end:calc(var(--rs-aligner-p-h) * -1)}.root.--side-block [data-rs-aligner-target],.root.--side-top [data-rs-aligner-target]{margin-block-start:calc(var(--rs-aligner-p-v) * -1)}.root.--side-block [data-rs-aligner-target],.root.--side-bottom [data-rs-aligner-target]{margin-block-end:calc(var(--rs-aligner-p-v) * -1)}
@@ -50,6 +50,7 @@ export type TriggerAttributes = {
50
50
  ref: React.RefObject<HTMLButtonElement>;
51
51
  onBlur?: (e: React.FocusEvent) => void;
52
52
  onFocus?: () => void;
53
+ onMouseDown?: () => void;
53
54
  onMouseEnter?: () => void;
54
55
  onMouseLeave?: () => void;
55
56
  onTouchStart?: () => void;
@@ -107,6 +108,7 @@ export type ContextProps = {
107
108
  handleOpen: () => void;
108
109
  handleMouseEnter: () => void;
109
110
  handleMouseLeave: () => void;
111
+ handleMouseDown: () => void;
110
112
  handleTransitionEnd: (e: React.TransitionEvent) => void;
111
113
  handleTransitionStart: (e: TransitionEvent) => void;
112
114
  handleClick: () => void;
@@ -33,6 +33,7 @@ const FlyoutRoot = (props) => {
33
33
  */
34
34
  const triggerElRef = (!parentFlyoutContentContext && parentFlyoutTriggerContext?.triggerElRef) ||
35
35
  internalTriggerElRef;
36
+ const triggerBoundsRef = React.useRef();
36
37
  const flyoutElRef = React.useRef(null);
37
38
  const id = useElementId(passedId);
38
39
  const timerRef = React.useRef();
@@ -48,7 +49,10 @@ const FlyoutRoot = (props) => {
48
49
  // Touch devices trigger onMouseEnter but we don't need to apply regular hover timeouts
49
50
  // So we're saving a flag on touch start and then change the mouse enter behavior
50
51
  const hoverTriggeredWithTouchEventRef = React.useRef(false);
51
- const flyout = useFlyout(triggerElRef, flyoutElRef, {
52
+ const flyout = useFlyout({
53
+ triggerElRef,
54
+ flyoutElRef,
55
+ triggerBoundsRef,
52
56
  width,
53
57
  position: passedPosition,
54
58
  defaultActive: resolvedActive,
@@ -91,24 +95,22 @@ const FlyoutRoot = (props) => {
91
95
  if (
92
96
  // Empty flyouts don't move the focus so they have to be closed on blur
93
97
  focusedContent ||
94
- // Content menu keeps the focus on the original trigger so moving the focus away from it shouldn't close it
95
- (triggerType === "hover" && trapFocusMode === "content-menu") ||
96
98
  // Prevent from closing in case user interacts with items inside content
97
99
  lockedBlurEffects.current) {
98
100
  return;
99
101
  }
100
102
  handleClose();
101
- }, [handleClose, triggerType, trapFocusMode]);
102
- const handleTouchStart = React.useCallback(() => {
103
- if (triggerType !== "hover")
104
- return;
105
- hoverTriggeredWithTouchEventRef.current = true;
106
- }, [triggerType]);
103
+ }, [handleClose]);
107
104
  const handleFocus = React.useCallback(() => {
108
105
  if (triggerType === "hover" && !checkKeyboardMode())
109
106
  return;
110
107
  handleOpen();
111
108
  }, [handleOpen, triggerType]);
109
+ const handleTouchStart = React.useCallback(() => {
110
+ if (triggerType !== "hover")
111
+ return;
112
+ hoverTriggeredWithTouchEventRef.current = true;
113
+ }, [triggerType]);
112
114
  const handleMouseEnter = React.useCallback(() => {
113
115
  clearTimer();
114
116
  if (hoverTriggeredWithTouchEventRef.current) {
@@ -134,6 +136,10 @@ const FlyoutRoot = (props) => {
134
136
  handleClose();
135
137
  }
136
138
  }, [status, handleOpen, handleClose]);
139
+ const handleTriggerMouseDown = React.useCallback(() => {
140
+ const rect = triggerElRef.current?.getBoundingClientRect();
141
+ triggerBoundsRef.current = rect;
142
+ }, [triggerElRef]);
137
143
  const handleContentMouseDown = () => {
138
144
  lockedBlurEffects.current = true;
139
145
  hoverTriggeredWithTouchEventRef.current = true;
@@ -277,6 +283,7 @@ const FlyoutRoot = (props) => {
277
283
  handleTouchStart,
278
284
  handleTransitionStart,
279
285
  handleTransitionEnd,
286
+ handleMouseDown: handleTriggerMouseDown,
280
287
  handleClick: handleTriggerClick,
281
288
  handleContentMouseDown,
282
289
  handleContentMouseUp,
@@ -3,12 +3,13 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useFlyoutContext, TriggerProvider } from "./Flyout.context.js";
4
4
  const FlyoutTrigger = (props) => {
5
5
  const { children } = props;
6
- const { id, triggerElRef, triggerType, flyout, handleFocus, handleBlur, handleMouseEnter, handleMouseLeave, handleTouchStart, handleClick, trapFocusMode, isSubmenu, } = useFlyoutContext();
6
+ const { id, triggerElRef, triggerType, flyout, handleFocus, handleBlur, handleMouseEnter, handleMouseLeave, handleMouseDown, handleTouchStart, handleClick, trapFocusMode, isSubmenu, } = useFlyoutContext();
7
7
  let childrenAttributes = {
8
8
  ref: triggerElRef,
9
9
  };
10
10
  if (triggerType === "click" || trapFocusMode === "action-menu") {
11
11
  childrenAttributes.onClick = handleClick;
12
+ childrenAttributes.onMouseDown = handleMouseDown;
12
13
  }
13
14
  if (triggerType === "hover") {
14
15
  childrenAttributes.onMouseEnter = handleMouseEnter;
@@ -91,6 +91,12 @@ export const modes = () => (<Example>
91
91
  </Demo>
92
92
  </Example.Item>
93
93
 
94
+ <Example.Item title="content-menu hover without buttons">
95
+ <Demo position="bottom-start" trapFocusMode="content-menu" triggerType="hover">
96
+ <div style={{ height: 50, width: 50, background: "tomato" }}/>
97
+ </Demo>
98
+ </Example.Item>
99
+
94
100
  <Example.Item title="content-menu hover">
95
101
  <Demo position="bottom-start" trapFocusMode="content-menu" triggerType="hover">
96
102
  <button type="button">Item 1</button>
@@ -11,7 +11,11 @@ type PassedFlyoutOptions = {
11
11
  forcePosition?: boolean;
12
12
  container?: HTMLElement | null;
13
13
  };
14
- type UseFlyout = (originRef: ElementRef, targetRef: ElementRef, options: PassedFlyoutOptions) => Pick<T.State, "styles" | "position" | "status"> & {
14
+ type UseFlyout = (args: PassedFlyoutOptions & {
15
+ triggerElRef: ElementRef;
16
+ flyoutElRef: ElementRef;
17
+ triggerBoundsRef: React.RefObject<DOMRect | undefined>;
18
+ }) => Pick<T.State, "styles" | "position" | "status"> & {
15
19
  updatePosition: (options?: {
16
20
  sync?: boolean;
17
21
  }) => void;
@@ -59,10 +59,11 @@ const resetStyles = {
59
59
  /**
60
60
  * Set position of the target element to fit on the screen
61
61
  */
62
- const flyout = (triggerEl, flyoutEl, options) => {
62
+ const flyout = (args) => {
63
+ const { triggerEl, flyoutEl, triggerBounds: passedTriggerBounds, ...options } = args;
63
64
  const { position, forcePosition, width, container } = options;
64
65
  const targetClone = flyoutEl.cloneNode(true);
65
- const triggerBounds = triggerEl.getBoundingClientRect();
66
+ const triggerBounds = passedTriggerBounds || triggerEl.getBoundingClientRect();
66
67
  // Reset all styles applied on the previous hook execution
67
68
  targetClone.style = "";
68
69
  Object.keys(resetStyles).forEach((key) => {
@@ -155,7 +156,8 @@ const flyoutReducer = (state, action) => {
155
156
  throw new Error("Invalid reducer type");
156
157
  }
157
158
  };
158
- const useFlyout = (originRef, targetRef, options) => {
159
+ const useFlyout = (args) => {
160
+ const { triggerElRef, flyoutElRef, triggerBoundsRef, ...options } = args;
159
161
  const { position: defaultPosition = "bottom", forcePosition, width, container } = options;
160
162
  const [isRTL] = useRTL();
161
163
  const [state, dispatch] = React.useReducer(flyoutReducer, {
@@ -176,9 +178,12 @@ const useFlyout = (originRef, targetRef, options) => {
176
178
  dispatch({ type: "remove" });
177
179
  }, []);
178
180
  const updatePosition = React.useCallback((options) => {
179
- if (!originRef.current || !targetRef.current)
181
+ if (!triggerElRef.current || !flyoutElRef.current)
180
182
  return;
181
- const nextFlyoutData = flyout(originRef.current, targetRef.current, {
183
+ const nextFlyoutData = flyout({
184
+ triggerEl: triggerElRef.current,
185
+ flyoutEl: flyoutElRef.current,
186
+ triggerBounds: triggerBoundsRef.current,
182
187
  width,
183
188
  position: defaultPosition,
184
189
  forcePosition,
@@ -187,7 +192,16 @@ const useFlyout = (originRef, targetRef, options) => {
187
192
  });
188
193
  if (nextFlyoutData)
189
194
  dispatch({ type: "position", payload: { ...nextFlyoutData, sync: options?.sync } });
190
- }, [container, defaultPosition, forcePosition, isRTL, originRef, targetRef, width]);
195
+ }, [
196
+ container,
197
+ defaultPosition,
198
+ forcePosition,
199
+ isRTL,
200
+ flyoutElRef,
201
+ triggerElRef,
202
+ triggerBoundsRef,
203
+ width,
204
+ ]);
191
205
  React.useEffect(() => {
192
206
  if (state.status === "rendered")
193
207
  updatePosition();
@@ -1,11 +1,11 @@
1
1
  import React from "react";
2
2
  export type Props = {
3
3
  children?: React.ReactNode;
4
- targetRef?: React.RefObject<HTMLElement | ShadowRoot | null>;
4
+ targetRef?: React.RefObject<HTMLElement | ShadowRoot>;
5
5
  };
6
6
  export type ScopeProps<T extends HTMLElement> = {
7
7
  children: (ref: React.RefObject<T>) => React.ReactNode;
8
8
  };
9
9
  export type Context = {
10
- scopeRef: React.RefObject<HTMLElement | null>;
10
+ scopeRef: React.RefObject<HTMLElement>;
11
11
  };
@@ -45,15 +45,12 @@ export const getTheme = (theme) => {
45
45
  config.textColor[cssTokenName] = configValue;
46
46
  config.colors[cssTokenName] = configValue;
47
47
  });
48
- Object.keys(definition.unit).forEach((tokenName) => {
48
+ Object.keys(definition.radius).forEach((tokenName) => {
49
49
  const cssTokenName = camelToKebab(tokenName);
50
- const cssVariable = ["rs", "unit", cssTokenName].join("-");
51
- const configValue = `var(--${cssVariable})`;
52
- if (tokenName.startsWith("radius")) {
53
- const name = cssTokenName.replace("radius-", "");
54
- config.borderRadius[name] = configValue;
55
- return;
56
- }
50
+ config.borderRadius[tokenName] = `var(--rs-radius-${cssTokenName})`;
51
+ return;
52
+ });
53
+ Object.keys(definition.unit).forEach((tokenName) => {
57
54
  if (tokenName.startsWith("base")) {
58
55
  [...Array(11).keys()].forEach((i) => {
59
56
  if (i === 0) {
@@ -63,7 +60,6 @@ export const getTheme = (theme) => {
63
60
  config.spacing[`x${i}`] = `var(--rs-unit-x${i})`;
64
61
  }
65
62
  });
66
- return;
67
63
  }
68
64
  });
69
65
  Object.keys(definition.shadow).forEach((tokenName) => {
@@ -8,3 +8,4 @@ export declare const RIGHT = "ArrowRight";
8
8
  export declare const LEFT = "ArrowLeft";
9
9
  export declare const HOME = "Home";
10
10
  export declare const END = "End";
11
+ export declare const BACKSPACE = "Backspace";
@@ -8,3 +8,4 @@ export const RIGHT = "ArrowRight";
8
8
  export const LEFT = "ArrowLeft";
9
9
  export const HOME = "Home";
10
10
  export const END = "End";
11
+ export const BACKSPACE = "Backspace";
@@ -10,17 +10,17 @@ type HotkeyOptions = {
10
10
  };
11
11
  type Context = {
12
12
  isPressed: (key: string) => boolean;
13
- addHotkeys: (hotkeys: Hotkeys, ref: React.RefObject<HTMLElement | null>, options?: HotkeyOptions) => (() => void) | undefined;
13
+ addHotkeys: (hotkeys: Hotkeys, ref: React.RefObject<HTMLElement>, options?: HotkeyOptions) => (() => void) | undefined;
14
14
  };
15
15
  type HotkeyData = {
16
16
  callback: Callback;
17
- ref: React.RefObject<HTMLElement | null>;
17
+ ref: React.RefObject<HTMLElement>;
18
18
  options: HotkeyOptions;
19
19
  };
20
20
  export declare class HotkeyStore {
21
21
  hotkeyMap: Record<string, Set<HotkeyData>>;
22
22
  getSize: () => number;
23
- bindHotkeys: (hotkeys: Hotkeys, ref: React.RefObject<HTMLElement | null>, options: HotkeyOptions) => void;
23
+ bindHotkeys: (hotkeys: Hotkeys, ref: React.RefObject<HTMLElement>, options: HotkeyOptions) => void;
24
24
  unbindHotkeys: (hotkeys: Hotkeys) => void;
25
25
  handleKeyDown: (pressedMap: PressedMap, e: KeyboardEvent) => void;
26
26
  }
@@ -10,7 +10,7 @@ declare const useDrag: <TriggerElement extends HTMLElement = HTMLButtonElement,
10
10
  containerRef?: React.RefObject<ContainerElement>;
11
11
  orientation?: "horizontal" | "vertical" | "all";
12
12
  }) => {
13
- ref: React.MutableRefObject<TriggerElement | null>;
13
+ ref: React.RefObject<TriggerElement>;
14
14
  containerRef: React.RefObject<ContainerElement>;
15
15
  active: boolean;
16
16
  };
@@ -36,11 +36,11 @@ const useResponsiveClientValue = (value) => {
36
36
  return value;
37
37
  }
38
38
  if (viewport === "xl")
39
- return value.xl || value.l || value.m || value.s;
39
+ return value.xl ?? value.l ?? value.m ?? value.s;
40
40
  if (viewport === "l")
41
- return value.l || value.m || value.s;
41
+ return value.l ?? value.m ?? value.s;
42
42
  if (viewport === "m")
43
- return value.m || value.s;
43
+ return value.m ?? value.s;
44
44
  return value.s;
45
45
  };
46
46
  export default useResponsiveClientValue;
@@ -0,0 +1,2 @@
1
+ declare const PlusIcon: () => import("react/jsx-runtime").JSX.Element;
2
+ export default PlusIcon;
@@ -0,0 +1,3 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ const PlusIcon = () => (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }), _jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })] }));
3
+ export default PlusIcon;
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export type { ActionBarProps } from "./components/ActionBar";
10
10
  export { default as Alert } from "./components/Alert";
11
11
  export type { AlertProps } from "./components/Alert";
12
12
  export { default as Autocomplete } from "./components/Autocomplete";
13
- export type { AutocompleteProps } from "./components/Autocomplete";
13
+ export type { AutocompleteProps, AutocompleteInstance } from "./components/Autocomplete";
14
14
  export { default as Avatar } from "./components/Avatar";
15
15
  export type { AvatarProps } from "./components/Avatar";
16
16
  export { default as Badge } from "./components/Badge";
@@ -0,0 +1,3 @@
1
+ import * as T from "../types";
2
+ declare const getTextAlignStyles: T.StaticStyleUtility<T.TextAlign>;
3
+ export default getTextAlignStyles;
@@ -0,0 +1,10 @@
1
+ import { responsiveClassNames } from "../../utilities/helpers.js";
2
+ import s from "./textAlign.module.css";
3
+ const getTextAlignStyles = (value) => {
4
+ if (!value)
5
+ return null;
6
+ return {
7
+ classNames: [...responsiveClassNames(s, "--text-align", value)],
8
+ };
9
+ };
10
+ export default getTextAlignStyles;
@@ -0,0 +1 @@
1
+ .--text-align-start{text-align:start}.--text-align-center{text-align:center}.--text-align-end{text-align:end}@media (--rs-viewport-m ){.--text-align-start--m{text-align:start}.--text-align-center--m{text-align:center}.--text-align-end--m{text-align:end}}@media (--rs-viewport-l ){.--text-align-start--l{text-align:start}.--text-align-center--l{text-align:center}.--text-align-end--l{text-align:end}}@media (--rs-viewport-xl ){.--text-align-start--xl{text-align:start}.--text-align-center--xl{text-align:center}.--text-align-end--xl{text-align:end}}
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import * as G from "../types/global";
3
+ export type TextAlign = "start" | "center" | "end";
3
4
  export type Radius = "small" | "medium" | "large" | "circular" | "none";
4
5
  export type Position = "relative" | "absolute" | "fixed" | "sticky" | "static";
5
6
  export type BorderColor = "neutral" | "neutral-faded" | "critical" | "critical-faded" | "warning" | "warning-faded" | "positive" | "positive-faded" | "primary" | "primary-faded" | "disabled" | "brand" | "transparent";
@@ -1,5 +1,5 @@
1
1
  import { getVariableName } from "../../utilities/css.js";
2
- const BASE_REM_SIZE = 14;
2
+ const BASE_REM_SIZE = 16;
3
3
  const transformedToken = (name, token) => {
4
4
  const result = [];
5
5
  result.push({
@@ -38,8 +38,8 @@ const generateColorValues = (args) => {
38
38
  */
39
39
  const bgHex = hex;
40
40
  const bgHexDark = okhslToHex(okhslDark);
41
- const bgFadedHsl = { ...okhsl, l: 0.94 + 0.045 * hueLightness };
42
- const bgFadedHslDark = { ...okhslDark, l: 0.16, s: okhslDark.s / 2 };
41
+ const bgFadedHsl = key === "neutral" ? { ...okhsl, l: 0.96 } : { ...okhsl, l: 0.94 + 0.045 * hueLightness };
42
+ const bgFadedHslDark = key === "neutral" ? { ...okhslDark, l: 0.15 } : { ...okhslDark, l: 0.16, s: okhslDark.s / 2 };
43
43
  const bgFadedHex = okhslToHex(bgFadedHsl);
44
44
  const bgFadedHexDark = okhslToHex(bgFadedHslDark);
45
45
  /**
@@ -1 +1 @@
1
- [data-rs-theme=figma]{--rs-font-family-title:Inter,BlinkMacSystemFont,-apple-system,Roboto,Helvetica,Arial,sans-serif;--rs-font-family-body:Inter,BlinkMacSystemFont,-apple-system,Roboto,Helvetica,Arial,sans-serif;--rs-font-weight-regular:400;--rs-font-weight-medium:500;--rs-font-weight-semibold:600;--rs-font-weight-bold:700;--rs-font-weight-extrabold:800;--rs-font-weight-black:900;--rs-font-size-title-1:5.714285714285714rem;--rs-line-height-title-1:6rem;--rs-font-family-title-1:var(--rs-font-family-title);--rs-font-weight-title-1:var(--rs-font-weight-semibold);--rs-letter-spacing-title-1:normal;--rs-font-size-title-2:4.571428571428571rem;--rs-line-height-title-2:4.857142857142857rem;--rs-font-family-title-2:var(--rs-font-family-title);--rs-font-weight-title-2:var(--rs-font-weight-semibold);--rs-letter-spacing-title-2:normal;--rs-font-size-title-3:4rem;--rs-line-height-title-3:4.285714285714286rem;--rs-font-family-title-3:var(--rs-font-family-title);--rs-font-weight-title-3:var(--rs-font-weight-semibold);--rs-letter-spacing-title-3:normal;--rs-font-size-title-4:2.857142857142857rem;--rs-line-height-title-4:3.142857142857143rem;--rs-font-family-title-4:var(--rs-font-family-title);--rs-font-weight-title-4:var(--rs-font-weight-semibold);--rs-letter-spacing-title-4:normal;--rs-font-size-title-5:2.5714285714285716rem;--rs-line-height-title-5:2.857142857142857rem;--rs-font-family-title-5:var(--rs-font-family-title);--rs-font-weight-title-5:var(--rs-font-weight-semibold);--rs-letter-spacing-title-5:normal;--rs-font-size-title-6:1.7142857142857142rem;--rs-line-height-title-6:2rem;--rs-font-family-title-6:var(--rs-font-family-title);--rs-font-weight-title-6:var(--rs-font-weight-semibold);--rs-letter-spacing-title-6:normal;--rs-font-size-featured-1:1.5714285714285714rem;--rs-line-height-featured-1:2rem;--rs-font-family-featured-1:var(--rs-font-family-body);--rs-letter-spacing-featured-1:normal;--rs-font-size-featured-2:1.4285714285714286rem;--rs-line-height-featured-2:2rem;--rs-font-family-featured-2:var(--rs-font-family-body);--rs-letter-spacing-featured-2:normal;--rs-font-size-featured-3:1.2857142857142858rem;--rs-line-height-featured-3:1.7142857142857142rem;--rs-font-family-featured-3:var(--rs-font-family-body);--rs-letter-spacing-featured-3:normal;--rs-font-size-body-1:1rem;--rs-line-height-body-1:1.4285714285714286rem;--rs-font-family-body-1:var(--rs-font-family-body);--rs-letter-spacing-body-1:normal;--rs-font-size-body-2:0.9285714285714286rem;--rs-line-height-body-2:1.4285714285714286rem;--rs-font-family-body-2:var(--rs-font-family-body);--rs-letter-spacing-body-2:normal;--rs-font-size-body-3:0.7857142857142857rem;--rs-line-height-body-3:1.1428571428571428rem;--rs-font-family-body-3:var(--rs-font-family-body);--rs-letter-spacing-body-3:normal;--rs-font-size-caption-1:0.7857142857142857rem;--rs-line-height-caption-1:1.1428571428571428rem;--rs-font-family-caption-1:var(--rs-font-family-body);--rs-letter-spacing-caption-1:normal;--rs-font-size-caption-2:0.7142857142857143rem;--rs-line-height-caption-2:0.8571428571428571rem;--rs-font-family-caption-2:var(--rs-font-family-body);--rs-letter-spacing-caption-2:normal;--rs-unit-base:4px;--rs-unit-radius-small:4px;--rs-unit-radius-medium:4px;--rs-unit-radius-large:4px;--rs-unit-x1:4px;--rs-unit-x2:8px;--rs-unit-x3:12px;--rs-unit-x4:16px;--rs-unit-x5:20px;--rs-unit-x6:24px;--rs-unit-x7:28px;--rs-unit-x8:32px;--rs-unit-x9:36px;--rs-unit-x10:40px;--rs-radius-small:4px;--rs-radius-medium:8px;--rs-radius-large:12px;--rs-color-brand:#5a58f2;--rs-color-white:#fff;--rs-color-black:#000;--rs-color-on-background-primary:#fff;--rs-color-on-background-critical:#000;--rs-color-on-background-warning:#000;--rs-color-on-background-positive:#000;--rs-color-on-brand:#fff;--rs-color-rgb-white:255,255,255;--rs-color-rgb-black:0,0,0;--rs-duration-fast:200ms;--rs-duration-medium:300ms;--rs-duration-slow:400ms;--rs-easing-standard:cubic-bezier(0.4,0,0.2,1);--rs-easing-accelerate:cubic-bezier(0.4,0,1,1);--rs-easing-decelerate:cubic-bezier(0,0,0.2,1);--rs-shadow-raised:0px 1px 3px 0px rgba(0,0,0,.15);--rs-shadow-overlay:0px 10px 24px 0px rgba(0,0,0,.1),0px 2px 5px 0px rgba(0,0,0,.04)}[data-rs-theme=figma][data-rs-color-mode=light]{--rs-color-background-primary:#0d99ff;--rs-color-background-primary-faded:#e5f4ff;--rs-color-border-primary:#007be5;--rs-color-border-primary-faded:#bde3ff;--rs-color-foreground-primary:#007be5;--rs-color-background-critical:#f24822;--rs-color-background-critical-faded:#ffe2e0;--rs-color-border-critical:#dc3412;--rs-color-border-critical-faded:#ffc7c2;--rs-color-foreground-critical:#dc3412;--rs-color-background-warning:#facc15;--rs-color-background-warning-faded:#fffae9;--rs-color-border-warning:#cfa90f;--rs-color-border-warning-faded:#faedbb;--rs-color-foreground-warning:#7b6305;--rs-color-background-positive:#14ae5c;--rs-color-background-positive-faded:#daecdf;--rs-color-border-positive:#009951;--rs-color-border-positive-faded:#bbddc6;--rs-color-foreground-positive:#009951;--rs-color-background-neutral:#dfe2ea;--rs-color-background-neutral-faded:#f5f5f5;--rs-color-border-neutral:#e6e6e6;--rs-color-border-neutral-faded:#e6e6e6;--rs-color-foreground-neutral:#191919;--rs-color-foreground-neutral-faded:#474747;--rs-color-background-disabled:#e4e4e4;--rs-color-background-disabled-faded:#f5f5f5;--rs-color-border-disabled:#e6e6e6;--rs-color-foreground-disabled:#b2b2b2;--rs-color-background-elevation-base:#fff;--rs-color-background-elevation-raised:#fff;--rs-color-background-elevation-overlay:#fff;--rs-color-background-page:#fff;--rs-color-background-page-faded:#fafafa;--rs-color-background-neutral-highlighted:#d4d8e3;--rs-color-background-primary-highlighted:#007be5;--rs-color-background-positive-highlighted:#009951;--rs-color-background-critical-highlighted:#dc3412;--rs-color-rgb-background-primary:13,153,255;--rs-color-rgb-background-primary-faded:229,244,255;--rs-color-rgb-background-critical:242,72,34;--rs-color-rgb-background-critical-faded:255,226,224;--rs-color-rgb-background-warning:250,204,21;--rs-color-rgb-background-warning-faded:255,250,233;--rs-color-rgb-background-positive:20,174,92;--rs-color-rgb-background-positive-faded:218,236,223;--rs-color-on-background-neutral:#000;--rs-color-rgb-background-neutral:223,226,234;--rs-color-rgb-background-neutral-faded:245,245,245;--rs-color-rgb-background-disabled:228,228,228;--rs-color-rgb-background-disabled-faded:245,245,245;--rs-color-rgb-background-elevation-base:255,255,255;--rs-color-rgb-background-elevation-raised:255,255,255;--rs-color-rgb-background-elevation-overlay:255,255,255;--rs-color-rgb-background-page:255,255,255;--rs-color-rgb-background-page-faded:250,250,250;--rs-color-rgb-background-neutral-highlighted:212,216,227;--rs-color-rgb-background-primary-highlighted:0,123,229;--rs-color-rgb-background-positive-highlighted:0,153,81;--rs-color-rgb-background-critical-highlighted:220,52,18}[data-rs-theme=figma][data-rs-color-mode=dark]{--rs-color-background-primary:#0c8ce9;--rs-color-background-primary-faded:#394360;--rs-color-border-primary:#7cc4f8;--rs-color-border-primary-faded:#2a4d72;--rs-color-foreground-primary:#7cc4f8;--rs-color-background-critical:#e03e1a;--rs-color-background-critical-faded:#60332a;--rs-color-border-critical:#fca397;--rs-color-border-critical-faded:#803226;--rs-color-foreground-critical:#fca397;--rs-color-background-warning:#f1c512;--rs-color-background-warning-faded:#2c271f;--rs-color-border-warning:#b4920a;--rs-color-border-warning-faded:#3d3628;--rs-color-foreground-warning:#b4920c;--rs-color-background-positive:#198f51;--rs-color-background-positive-faded:#3d5749;--rs-color-border-positive:#79d297;--rs-color-border-positive-faded:#086338;--rs-color-foreground-positive:#79d297;--rs-color-background-neutral:#444;--rs-color-background-neutral-faded:#383838;--rs-color-border-neutral:#444;--rs-color-border-neutral-faded:#444;--rs-color-foreground-neutral:#fff;--rs-color-foreground-neutral-faded:#b2b2b2;--rs-color-background-disabled:#474747;--rs-color-background-disabled-faded:#3a3a3a;--rs-color-border-disabled:#3e3e3e;--rs-color-foreground-disabled:#656565;--rs-color-background-elevation-base:#2c2c2c;--rs-color-background-elevation-raised:#2c2c2c;--rs-color-background-elevation-overlay:#2c2c2c;--rs-color-background-page:#2c2c2c;--rs-color-background-page-faded:#1e1e1e;--rs-color-background-neutral-highlighted:#525252;--rs-color-background-primary-highlighted:#0a6dc2;--rs-color-background-positive-highlighted:#078348;--rs-color-background-critical-highlighted:#c4381c;--rs-color-rgb-background-primary:12,140,233;--rs-color-rgb-background-primary-faded:57,67,96;--rs-color-rgb-background-critical:224,62,26;--rs-color-rgb-background-critical-faded:96,51,42;--rs-color-rgb-background-warning:241,197,18;--rs-color-rgb-background-warning-faded:44,39,31;--rs-color-rgb-background-positive:25,143,81;--rs-color-rgb-background-positive-faded:61,87,73;--rs-color-on-background-neutral:#fff;--rs-color-rgb-background-neutral:68,68,68;--rs-color-rgb-background-neutral-faded:56,56,56;--rs-color-rgb-background-disabled:71,71,71;--rs-color-rgb-background-disabled-faded:58,58,58;--rs-color-rgb-background-elevation-base:44,44,44;--rs-color-rgb-background-elevation-raised:44,44,44;--rs-color-rgb-background-elevation-overlay:44,44,44;--rs-color-rgb-background-page:44,44,44;--rs-color-rgb-background-page-faded:30,30,30;--rs-color-rgb-background-neutral-highlighted:82,82,82;--rs-color-rgb-background-primary-highlighted:10,109,194;--rs-color-rgb-background-positive-highlighted:7,131,72;--rs-color-rgb-background-critical-highlighted:196,56,28}
1
+ [data-rs-theme=figma]{--rs-font-family-title:Inter,BlinkMacSystemFont,-apple-system,Roboto,Helvetica,Arial,sans-serif;--rs-font-family-body:Inter,BlinkMacSystemFont,-apple-system,Roboto,Helvetica,Arial,sans-serif;--rs-font-weight-regular:400;--rs-font-weight-medium:500;--rs-font-weight-semibold:600;--rs-font-weight-bold:700;--rs-font-weight-extrabold:800;--rs-font-weight-black:900;--rs-font-size-title-1:5rem;--rs-line-height-title-1:5.25rem;--rs-font-family-title-1:var(--rs-font-family-title);--rs-font-weight-title-1:var(--rs-font-weight-semibold);--rs-letter-spacing-title-1:normal;--rs-font-size-title-2:4rem;--rs-line-height-title-2:4.25rem;--rs-font-family-title-2:var(--rs-font-family-title);--rs-font-weight-title-2:var(--rs-font-weight-semibold);--rs-letter-spacing-title-2:normal;--rs-font-size-title-3:3.5rem;--rs-line-height-title-3:3.75rem;--rs-font-family-title-3:var(--rs-font-family-title);--rs-font-weight-title-3:var(--rs-font-weight-semibold);--rs-letter-spacing-title-3:normal;--rs-font-size-title-4:2.5rem;--rs-line-height-title-4:2.75rem;--rs-font-family-title-4:var(--rs-font-family-title);--rs-font-weight-title-4:var(--rs-font-weight-semibold);--rs-letter-spacing-title-4:normal;--rs-font-size-title-5:2.25rem;--rs-line-height-title-5:2.5rem;--rs-font-family-title-5:var(--rs-font-family-title);--rs-font-weight-title-5:var(--rs-font-weight-semibold);--rs-letter-spacing-title-5:normal;--rs-font-size-title-6:1.5rem;--rs-line-height-title-6:1.75rem;--rs-font-family-title-6:var(--rs-font-family-title);--rs-font-weight-title-6:var(--rs-font-weight-semibold);--rs-letter-spacing-title-6:normal;--rs-font-size-featured-1:1.375rem;--rs-line-height-featured-1:1.75rem;--rs-font-family-featured-1:var(--rs-font-family-body);--rs-letter-spacing-featured-1:normal;--rs-font-size-featured-2:1.25rem;--rs-line-height-featured-2:1.75rem;--rs-font-family-featured-2:var(--rs-font-family-body);--rs-letter-spacing-featured-2:normal;--rs-font-size-featured-3:1.125rem;--rs-line-height-featured-3:1.5rem;--rs-font-family-featured-3:var(--rs-font-family-body);--rs-letter-spacing-featured-3:normal;--rs-font-size-body-1:0.875rem;--rs-line-height-body-1:1.25rem;--rs-font-family-body-1:var(--rs-font-family-body);--rs-letter-spacing-body-1:normal;--rs-font-size-body-2:0.8125rem;--rs-line-height-body-2:1.25rem;--rs-font-family-body-2:var(--rs-font-family-body);--rs-letter-spacing-body-2:normal;--rs-font-size-body-3:0.6875rem;--rs-line-height-body-3:1rem;--rs-font-family-body-3:var(--rs-font-family-body);--rs-letter-spacing-body-3:normal;--rs-font-size-caption-1:0.6875rem;--rs-line-height-caption-1:1rem;--rs-font-family-caption-1:var(--rs-font-family-body);--rs-letter-spacing-caption-1:normal;--rs-font-size-caption-2:0.625rem;--rs-line-height-caption-2:0.75rem;--rs-font-family-caption-2:var(--rs-font-family-body);--rs-letter-spacing-caption-2:normal;--rs-unit-base:4px;--rs-unit-radius-small:4px;--rs-unit-radius-medium:4px;--rs-unit-radius-large:4px;--rs-unit-x1:4px;--rs-unit-x2:8px;--rs-unit-x3:12px;--rs-unit-x4:16px;--rs-unit-x5:20px;--rs-unit-x6:24px;--rs-unit-x7:28px;--rs-unit-x8:32px;--rs-unit-x9:36px;--rs-unit-x10:40px;--rs-radius-small:4px;--rs-radius-medium:8px;--rs-radius-large:12px;--rs-color-brand:#5a58f2;--rs-color-white:#fff;--rs-color-black:#000;--rs-color-on-background-primary:#fff;--rs-color-on-background-critical:#000;--rs-color-on-background-warning:#000;--rs-color-on-background-positive:#000;--rs-color-on-brand:#fff;--rs-color-rgb-white:255,255,255;--rs-color-rgb-black:0,0,0;--rs-duration-fast:200ms;--rs-duration-medium:300ms;--rs-duration-slow:400ms;--rs-easing-standard:cubic-bezier(0.4,0,0.2,1);--rs-easing-accelerate:cubic-bezier(0.4,0,1,1);--rs-easing-decelerate:cubic-bezier(0,0,0.2,1);--rs-shadow-raised:0px 1px 3px 0px rgba(0,0,0,.15);--rs-shadow-overlay:0px 10px 24px 0px rgba(0,0,0,.1),0px 2px 5px 0px rgba(0,0,0,.04)}[data-rs-theme=figma][data-rs-color-mode=light]{--rs-color-background-primary:#0d99ff;--rs-color-background-primary-faded:#e5f4ff;--rs-color-border-primary:#007be5;--rs-color-border-primary-faded:#bde3ff;--rs-color-foreground-primary:#007be5;--rs-color-background-critical:#f24822;--rs-color-background-critical-faded:#ffe2e0;--rs-color-border-critical:#dc3412;--rs-color-border-critical-faded:#ffc7c2;--rs-color-foreground-critical:#dc3412;--rs-color-background-warning:#facc15;--rs-color-background-warning-faded:#fffae9;--rs-color-border-warning:#cfa90f;--rs-color-border-warning-faded:#faedbb;--rs-color-foreground-warning:#7b6305;--rs-color-background-positive:#14ae5c;--rs-color-background-positive-faded:#daecdf;--rs-color-border-positive:#009951;--rs-color-border-positive-faded:#bbddc6;--rs-color-foreground-positive:#009951;--rs-color-background-neutral:#dfe2ea;--rs-color-background-neutral-faded:#f5f5f5;--rs-color-border-neutral:#e6e6e6;--rs-color-border-neutral-faded:#e6e6e6;--rs-color-foreground-neutral:#191919;--rs-color-foreground-neutral-faded:#474747;--rs-color-background-disabled:#e4e4e4;--rs-color-background-disabled-faded:#f5f5f5;--rs-color-border-disabled:#e6e6e6;--rs-color-foreground-disabled:#b2b2b2;--rs-color-background-elevation-base:#fff;--rs-color-background-elevation-raised:#fff;--rs-color-background-elevation-overlay:#fff;--rs-color-background-page:#fff;--rs-color-background-page-faded:#fafafa;--rs-color-background-neutral-highlighted:#d4d8e3;--rs-color-background-primary-highlighted:#007be5;--rs-color-background-positive-highlighted:#009951;--rs-color-background-critical-highlighted:#dc3412;--rs-color-rgb-background-primary:13,153,255;--rs-color-rgb-background-primary-faded:229,244,255;--rs-color-rgb-background-critical:242,72,34;--rs-color-rgb-background-critical-faded:255,226,224;--rs-color-rgb-background-warning:250,204,21;--rs-color-rgb-background-warning-faded:255,250,233;--rs-color-rgb-background-positive:20,174,92;--rs-color-rgb-background-positive-faded:218,236,223;--rs-color-on-background-neutral:#000;--rs-color-rgb-background-neutral:223,226,234;--rs-color-rgb-background-neutral-faded:245,245,245;--rs-color-rgb-background-disabled:228,228,228;--rs-color-rgb-background-disabled-faded:245,245,245;--rs-color-rgb-background-elevation-base:255,255,255;--rs-color-rgb-background-elevation-raised:255,255,255;--rs-color-rgb-background-elevation-overlay:255,255,255;--rs-color-rgb-background-page:255,255,255;--rs-color-rgb-background-page-faded:250,250,250;--rs-color-rgb-background-neutral-highlighted:212,216,227;--rs-color-rgb-background-primary-highlighted:0,123,229;--rs-color-rgb-background-positive-highlighted:0,153,81;--rs-color-rgb-background-critical-highlighted:220,52,18}[data-rs-theme=figma][data-rs-color-mode=dark]{--rs-color-background-primary:#0c8ce9;--rs-color-background-primary-faded:#394360;--rs-color-border-primary:#7cc4f8;--rs-color-border-primary-faded:#2a4d72;--rs-color-foreground-primary:#7cc4f8;--rs-color-background-critical:#e03e1a;--rs-color-background-critical-faded:#60332a;--rs-color-border-critical:#fca397;--rs-color-border-critical-faded:#803226;--rs-color-foreground-critical:#fca397;--rs-color-background-warning:#f1c512;--rs-color-background-warning-faded:#2c271f;--rs-color-border-warning:#b4920a;--rs-color-border-warning-faded:#3d3628;--rs-color-foreground-warning:#b4920c;--rs-color-background-positive:#198f51;--rs-color-background-positive-faded:#3d5749;--rs-color-border-positive:#79d297;--rs-color-border-positive-faded:#086338;--rs-color-foreground-positive:#79d297;--rs-color-background-neutral:#444;--rs-color-background-neutral-faded:#383838;--rs-color-border-neutral:#444;--rs-color-border-neutral-faded:#444;--rs-color-foreground-neutral:#fff;--rs-color-foreground-neutral-faded:#b2b2b2;--rs-color-background-disabled:#474747;--rs-color-background-disabled-faded:#3a3a3a;--rs-color-border-disabled:#3e3e3e;--rs-color-foreground-disabled:#656565;--rs-color-background-elevation-base:#2c2c2c;--rs-color-background-elevation-raised:#2c2c2c;--rs-color-background-elevation-overlay:#2c2c2c;--rs-color-background-page:#2c2c2c;--rs-color-background-page-faded:#1e1e1e;--rs-color-background-neutral-highlighted:#525252;--rs-color-background-primary-highlighted:#0a6dc2;--rs-color-background-positive-highlighted:#078348;--rs-color-background-critical-highlighted:#c4381c;--rs-color-rgb-background-primary:12,140,233;--rs-color-rgb-background-primary-faded:57,67,96;--rs-color-rgb-background-critical:224,62,26;--rs-color-rgb-background-critical-faded:96,51,42;--rs-color-rgb-background-warning:241,197,18;--rs-color-rgb-background-warning-faded:44,39,31;--rs-color-rgb-background-positive:25,143,81;--rs-color-rgb-background-positive-faded:61,87,73;--rs-color-on-background-neutral:#fff;--rs-color-rgb-background-neutral:68,68,68;--rs-color-rgb-background-neutral-faded:56,56,56;--rs-color-rgb-background-disabled:71,71,71;--rs-color-rgb-background-disabled-faded:58,58,58;--rs-color-rgb-background-elevation-base:44,44,44;--rs-color-rgb-background-elevation-raised:44,44,44;--rs-color-rgb-background-elevation-overlay:44,44,44;--rs-color-rgb-background-page:44,44,44;--rs-color-rgb-background-page-faded:30,30,30;--rs-color-rgb-background-neutral-highlighted:82,82,82;--rs-color-rgb-background-primary-highlighted:10,109,194;--rs-color-rgb-background-positive-highlighted:7,131,72;--rs-color-rgb-background-critical-highlighted:196,56,28}