reshaped 3.0.3 → 3.0.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 (48) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/dist/bundle.css +1 -1
  3. package/dist/bundle.d.ts +3 -3
  4. package/dist/bundle.js +10 -10
  5. package/dist/components/Autocomplete/Autocomplete.js +2 -2
  6. package/dist/components/Autocomplete/Autocomplete.types.d.ts +2 -1
  7. package/dist/components/Carousel/Carousel.types.d.ts +2 -2
  8. package/dist/components/Carousel/index.d.ts +1 -1
  9. package/dist/components/DropdownMenu/DropdownMenu.types.d.ts +3 -2
  10. package/dist/components/DropdownMenu/index.d.ts +1 -1
  11. package/dist/components/Modal/Modal.js +9 -4
  12. package/dist/components/Popover/Popover.js +2 -2
  13. package/dist/components/Popover/Popover.types.d.ts +3 -2
  14. package/dist/components/Popover/index.d.ts +1 -1
  15. package/dist/components/Text/Text.js +1 -1
  16. package/dist/components/Text/Text.module.css +1 -1
  17. package/dist/components/Text/Text.types.d.ts +1 -1
  18. package/dist/components/Text/tests/Text.stories.js +3 -0
  19. package/dist/components/Tooltip/Tooltip.js +2 -2
  20. package/dist/components/Tooltip/Tooltip.types.d.ts +1 -1
  21. package/dist/components/Tooltip/tests/Tooltip.stories.js +25 -1
  22. package/dist/components/View/View.js +3 -1
  23. package/dist/components/View/View.module.css +1 -1
  24. package/dist/components/View/View.types.d.ts +1 -1
  25. package/dist/components/View/tests/View.stories.js +6 -0
  26. package/dist/components/_private/Flyout/Flyout.constants.d.ts +3 -0
  27. package/dist/components/_private/Flyout/Flyout.constants.js +3 -0
  28. package/dist/components/_private/Flyout/Flyout.module.css +1 -1
  29. package/dist/components/_private/Flyout/Flyout.types.d.ts +9 -3
  30. package/dist/components/_private/Flyout/FlyoutContent.js +7 -4
  31. package/dist/components/_private/Flyout/FlyoutControlled.js +33 -18
  32. package/dist/components/_private/Flyout/index.d.ts +1 -1
  33. package/dist/components/_private/Flyout/tests/Flyout.stories.d.ts +3 -0
  34. package/dist/components/_private/Flyout/tests/Flyout.stories.js +62 -0
  35. package/dist/components/_private/Flyout/useFlyout.d.ts +4 -1
  36. package/dist/components/_private/Flyout/useFlyout.js +21 -16
  37. package/dist/components/_private/Flyout/utilities/calculatePosition.d.ts +1 -0
  38. package/dist/components/_private/Flyout/utilities/calculatePosition.js +3 -3
  39. package/dist/components/_private/Flyout/utilities/cooldown.d.ts +8 -0
  40. package/dist/components/_private/Flyout/utilities/cooldown.js +18 -0
  41. package/dist/index.d.ts +3 -3
  42. package/dist/styles/border/border.module.css +1 -0
  43. package/dist/styles/border/index.d.ts +3 -0
  44. package/dist/styles/border/index.js +10 -0
  45. package/dist/styles/types.d.ts +1 -0
  46. package/package.json +1 -1
  47. package/dist/constants/timeouts.d.ts +0 -2
  48. package/dist/constants/timeouts.js +0 -2
@@ -1,9 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import React from "react";
4
- import { debounce } from "../../../utilities/helpers.js";
5
4
  import TrapFocus from "../../../utilities/a11y/TrapFocus.js";
6
- import * as timeouts from "../../../constants/timeouts.js";
7
5
  import useIsDismissible from "../../../hooks/_private/useIsDismissible.js";
8
6
  import useElementId from "../../../hooks/useElementId.js";
9
7
  import useIsomorphicLayoutEffect from "../../../hooks/useIsomorphicLayoutEffect.js";
@@ -12,11 +10,15 @@ import useOnClickOutside from "../../../hooks/_private/useOnClickOutside.js";
12
10
  import useRTL from "../../../hooks/useRTL.js";
13
11
  import { checkTransitions, onNextFrame } from "../../../utilities/animation.js";
14
12
  import useFlyout from "./useFlyout.js";
13
+ import * as timeouts from "./Flyout.constants.js";
14
+ import cooldown from "./utilities/cooldown.js";
15
15
  import { Provider, useFlyoutTriggerContext, useFlyoutContext } from "./Flyout.context.js";
16
16
  const FlyoutRoot = (props) => {
17
- const { triggerType = "click", onOpen, onClose, children, forcePosition, trapFocusMode, width, disableHideAnimation, contentGap, contentClassName, contentAttributes, position: passedPosition, active: passedActive, id: passedId, instanceRef, } = props;
17
+ const { triggerType = "click", onOpen, onClose, children, disabled, forcePosition, trapFocusMode, width, disableHideAnimation, disableContentHover, contentGap, contentClassName, contentAttributes, position: passedPosition, active: passedActive, id: passedId, instanceRef, containerRef, } = props;
18
18
  const parentFlyoutContext = useFlyoutContext();
19
19
  const parentFlyoutTriggerContext = useFlyoutTriggerContext();
20
+ const isSubmenu = parentFlyoutContext.trapFocusMode === "action-menu" ||
21
+ parentFlyoutContext.trapFocusMode === "content-menu";
20
22
  const [isRTL] = useRTL();
21
23
  const internalTriggerElRef = React.useRef(null);
22
24
  /**
@@ -36,6 +38,7 @@ const FlyoutRoot = (props) => {
36
38
  width,
37
39
  position: passedPosition,
38
40
  defaultActive: passedActive,
41
+ container: containerRef?.current,
39
42
  forcePosition,
40
43
  });
41
44
  const { status, updatePosition, render, hide, remove, show } = flyout;
@@ -50,24 +53,23 @@ const FlyoutRoot = (props) => {
50
53
  * Called from the internal actions
51
54
  */
52
55
  const handleOpen = React.useCallback(() => {
53
- const canOpen = !lockedRef.current && status === "idle";
56
+ const canOpen = !lockedRef.current && status === "idle" && !disabled;
54
57
  if (!canOpen)
55
58
  return;
56
59
  onOpen?.();
57
60
  // eslint-disable-next-line react-hooks/exhaustive-deps
58
- }, [status]);
61
+ }, [status, disabled]);
59
62
  const handleClose = React.useCallback((options) => {
60
63
  const isLocked = triggerType === "click" && !isDismissible();
61
- const canClose = !isLocked && status !== "idle";
64
+ const canClose = !isLocked && status !== "idle" && !disabled;
62
65
  if (!canClose)
63
66
  return;
64
67
  onClose?.();
65
- if (options?.closeParents) {
68
+ if (options?.closeParents)
66
69
  parentFlyoutContext?.handleClose?.();
67
- }
68
70
  },
69
71
  // eslint-disable-next-line react-hooks/exhaustive-deps
70
- [status, isDismissible, triggerType]);
72
+ [status, isDismissible, triggerType, disabled]);
71
73
  /**
72
74
  * Trigger event handlers
73
75
  */
@@ -89,9 +91,12 @@ const FlyoutRoot = (props) => {
89
91
  }, [handleOpen]);
90
92
  const handleMouseEnter = React.useCallback(() => {
91
93
  clearTimer();
92
- timerRef.current = setTimeout(handleOpen, timeouts.mouseEnter);
93
- }, [clearTimer, timerRef, handleOpen]);
94
+ timerRef.current = setTimeout(handleOpen, cooldown.timer || isSubmenu ? timeouts.mouseEnterShort : timeouts.mouseEnter);
95
+ if (!isSubmenu)
96
+ cooldown.warm();
97
+ }, [clearTimer, timerRef, handleOpen, isSubmenu]);
94
98
  const handleMouseLeave = React.useCallback(() => {
99
+ cooldown.cool();
95
100
  clearTimer();
96
101
  timerRef.current = setTimeout(() => handleClose(), timeouts.mouseLeave);
97
102
  }, [clearTimer, timerRef, handleClose]);
@@ -130,9 +135,13 @@ const FlyoutRoot = (props) => {
130
135
  }
131
136
  /**
132
137
  * Check that transitions are enabled and it has been triggered on tooltip open
133
- * (keyboard focus navigation could move too fast and ignore the transitions completely)
138
+ * - keyboard focus navigation could move too fast and ignore the transitions completely
139
+ * - warmed up tooltips get removed instantly
134
140
  */
135
- if (checkTransitions() && !disableHideAnimation && transitionStartedRef.current) {
141
+ if (checkTransitions() &&
142
+ !disableHideAnimation &&
143
+ transitionStartedRef.current &&
144
+ cooldown.status !== "warm") {
136
145
  hide();
137
146
  }
138
147
  else {
@@ -193,10 +202,12 @@ const FlyoutRoot = (props) => {
193
202
  * Update position on resize or RTL
194
203
  */
195
204
  React.useEffect(() => {
196
- const update = debounce(updatePosition, 10);
197
- window.addEventListener("resize", update);
198
- return () => window.removeEventListener("resize", update);
199
- }, [updatePosition]);
205
+ const resizeObserver = new ResizeObserver(() => updatePosition({ sync: true }));
206
+ resizeObserver.observe(document.body);
207
+ if (triggerElRef.current)
208
+ resizeObserver.observe(triggerElRef.current);
209
+ return () => resizeObserver.disconnect();
210
+ }, [updatePosition, triggerElRef]);
200
211
  React.useEffect(() => {
201
212
  updatePosition();
202
213
  }, [isRTL, updatePosition]);
@@ -206,7 +217,8 @@ const FlyoutRoot = (props) => {
206
217
  React.useImperativeHandle(instanceRef, () => ({
207
218
  open: handleOpen,
208
219
  close: handleClose,
209
- }), [handleOpen, handleClose]);
220
+ updatePosition: () => updatePosition({ sync: true }),
221
+ }), [handleOpen, handleClose, updatePosition]);
210
222
  useHotkeys({ Escape: () => handleClose() }, [handleClose]);
211
223
  useOnClickOutside([flyoutElRef, triggerElRef], () => {
212
224
  // Clicking outside changes focused element so we don't need to set it back ourselves
@@ -235,6 +247,9 @@ const FlyoutRoot = (props) => {
235
247
  contentGap,
236
248
  contentClassName,
237
249
  contentAttributes,
250
+ containerRef,
251
+ disableContentHover,
252
+ isSubmenu,
238
253
  }, children: children }));
239
254
  };
240
255
  export default FlyoutRoot;
@@ -1,3 +1,3 @@
1
1
  export { default } from "./Flyout";
2
2
  export { useFlyoutContext } from "./Flyout.context";
3
- export type { Props as FlyoutProps, InstanceRef as FlyoutInstanceRef, TriggerProps as FlyoutTriggerProps, ContentProps as FlyoutContentProps, } from "./Flyout.types";
3
+ export type { Props as FlyoutProps, Instance as FlyoutInstance, TriggerProps as FlyoutTriggerProps, ContentProps as FlyoutContentProps, } from "./Flyout.types";
@@ -11,8 +11,11 @@ export declare const modeContentMenuClick: () => React.JSX.Element;
11
11
  export declare const modeDialogHover: () => React.JSX.Element;
12
12
  export declare const modeActionMenuHover: () => React.JSX.Element;
13
13
  export declare const modeContentMenuHover: () => React.JSX.Element;
14
+ export declare const disableContentHover: () => React.JSX.Element;
15
+ export declare const customPortalTarget: () => React.JSX.Element;
14
16
  export declare const testWidthOverflowOnMobile: () => React.JSX.Element;
15
17
  export declare const testInsideScrollArea: () => React.JSX.Element;
16
18
  export declare const testInsideFixed: () => React.JSX.Element;
19
+ export declare const testDynamicBounds: () => React.JSX.Element;
17
20
  export declare const widthTrigger: () => React.JSX.Element;
18
21
  export declare const scopedTheming: () => React.JSX.Element;
@@ -78,6 +78,31 @@ export const modeContentMenuHover = () => (<Demo position="bottom-start" trapFoc
78
78
  <button type="button">Item 2</button>
79
79
  <button type="button">Close</button>
80
80
  </Demo>);
81
+ export const disableContentHover = () => (<Demo triggerType="hover" disableContentHover>
82
+ Content
83
+ </Demo>);
84
+ export const customPortalTarget = () => {
85
+ const portalRef = React.useRef(null);
86
+ return (<div style={{ position: "relative", padding: 16, height: 200, overflow: "auto" }} ref={portalRef}>
87
+ <Flyout position="bottom-start" containerRef={portalRef} active>
88
+ <Flyout.Trigger>{(attributes) => <button {...attributes}>Open</button>}</Flyout.Trigger>
89
+ <Flyout.Content>
90
+ <div style={{
91
+ background: "var(--rs-color-background-elevation-overlay)",
92
+ padding: "var(--rs-unit-x4)",
93
+ height: 100,
94
+ width: 160,
95
+ borderRadius: "var(--rs-radius-medium)",
96
+ border: "1px solid var(--rs-color-border-neutral-faded)",
97
+ boxSizing: "border-box",
98
+ }}>
99
+ {"Content"}
100
+ </div>
101
+ </Flyout.Content>
102
+ </Flyout>
103
+ <div style={{ height: 1000 }}/>
104
+ </div>);
105
+ };
81
106
  export const testWidthOverflowOnMobile = () => (<Demo position="bottom-start" width={600}>
82
107
  Should work on mobile
83
108
  <button type="button">Item 1</button>
@@ -131,6 +156,43 @@ export const testInsideFixed = () => (<Example>
131
156
  <div style={{ height: 2000 }}/>
132
157
  </Example.Item>
133
158
  </Example>);
159
+ export const testDynamicBounds = () => {
160
+ const [left, setLeft] = React.useState("50%");
161
+ const [size, setSize] = React.useState("medium");
162
+ return (<View gap={4}>
163
+ <View direction="row" gap={2}>
164
+ <Button onClick={() => setLeft("0%")}>Left</Button>
165
+ <Button onClick={() => setLeft("50%")}>Center</Button>
166
+ <Button onClick={() => setLeft("100%")}>Right</Button>
167
+ <Button onClick={() => setSize("large")}>Large button</Button>
168
+ <Button onClick={() => setSize("medium")}>Small button</Button>
169
+ </View>
170
+ <View height={100}>
171
+ <Flyout position="bottom" active>
172
+ <Flyout.Trigger>
173
+ {(attributes) => (<div style={{ position: "absolute", left, top: "50%" }}>
174
+ <Button color="primary" attributes={attributes} size={size}>
175
+ Open
176
+ </Button>
177
+ </div>)}
178
+ </Flyout.Trigger>
179
+ <Flyout.Content>
180
+ <div style={{
181
+ background: "var(--rs-color-background-elevation-overlay)",
182
+ padding: "var(--rs-unit-x4)",
183
+ height: 100,
184
+ width: 160,
185
+ borderRadius: "var(--rs-radius-medium)",
186
+ border: "1px solid var(--rs-color-border-neutral-faded)",
187
+ boxSizing: "border-box",
188
+ }}>
189
+ {"Content"}
190
+ </div>
191
+ </Flyout.Content>
192
+ </Flyout>
193
+ </View>
194
+ </View>);
195
+ };
134
196
  export const widthTrigger = () => (<Flyout triggerType="click" width="trigger" position="bottom">
135
197
  <Flyout.Trigger>
136
198
  {(attributes) => <button {...attributes}>Trigger with long text</button>}
@@ -9,9 +9,12 @@ type PassedFlyoutOptions = {
9
9
  position?: T.Position;
10
10
  defaultActive?: boolean;
11
11
  forcePosition?: boolean;
12
+ container?: HTMLElement | null;
12
13
  };
13
14
  type UseFlyout = (originRef: ElementRef, targetRef: ElementRef, options: PassedFlyoutOptions) => Pick<T.State, "styles" | "position" | "status"> & {
14
- updatePosition: () => void;
15
+ updatePosition: (options?: {
16
+ sync?: boolean;
17
+ }) => void;
15
18
  render: () => void;
16
19
  hide: () => void;
17
20
  remove: () => void;
@@ -23,16 +23,17 @@ const getPositionOrder = (position) => {
23
23
  /**
24
24
  * Check if element visually fits on the screen
25
25
  */
26
- const fullyVisible = (bounds) => {
26
+ const fullyVisible = (args) => {
27
+ const { styles, scopeOffset } = args;
27
28
  const htmlEl = document.documentElement;
28
29
  const pageLeft = htmlEl.scrollLeft;
29
30
  const pageRight = pageLeft + htmlEl.clientWidth;
30
31
  const pageTop = htmlEl.scrollTop;
31
32
  const pageBottom = pageTop + htmlEl.clientHeight;
32
- return (bounds.left >= pageLeft &&
33
- bounds.left + bounds.width <= pageRight &&
34
- bounds.top >= pageTop &&
35
- bounds.top + bounds.height <= pageBottom);
33
+ return (styles.left + scopeOffset.left >= pageLeft &&
34
+ styles.left + styles.width + scopeOffset.left <= pageRight &&
35
+ styles.top + scopeOffset.top >= pageTop &&
36
+ styles.top + styles.height + scopeOffset.top <= pageBottom);
36
37
  };
37
38
  /**
38
39
  * Order of keys here is responsible for the order of styles applied
@@ -59,7 +60,7 @@ const resetStyles = {
59
60
  * Set position of the target element to fit on the screen
60
61
  */
61
62
  const flyout = (triggerEl, flyoutEl, options) => {
62
- const { position, forcePosition, width } = options;
63
+ const { position, forcePosition, width, container } = options;
63
64
  const targetClone = flyoutEl.cloneNode(true);
64
65
  const triggerBounds = triggerEl.getBoundingClientRect();
65
66
  // Reset all styles applied on the previous hook execution
@@ -78,14 +79,14 @@ const flyout = (triggerEl, flyoutEl, options) => {
78
79
  }
79
80
  document.body.appendChild(targetClone);
80
81
  const flyoutBounds = targetClone.getBoundingClientRect();
81
- const scrollableParent = getClosestFlyoutTarget(triggerEl);
82
+ const scrollableParent = container || getClosestFlyoutTarget(triggerEl);
82
83
  const scopeBounds = scrollableParent.getBoundingClientRect();
83
84
  const scopeOffset = {
84
85
  top: scopeBounds.top + document.documentElement.scrollTop - scrollableParent.scrollTop,
85
86
  left: scopeBounds.left + document.documentElement.scrollLeft - scrollableParent.scrollLeft,
86
87
  };
87
88
  let calculated = calculatePosition({ triggerBounds, flyoutBounds, scopeOffset, ...options });
88
- if (!fullyVisible(calculated.styles) && !forcePosition) {
89
+ if (!fullyVisible(calculated) && !forcePosition) {
89
90
  const order = getPositionOrder(position);
90
91
  const mobileOrder = order.filter((position) => position === "top" || position === "bottom");
91
92
  const test = (testOrder, extraOptions = {}) => {
@@ -102,7 +103,7 @@ const flyout = (triggerEl, flyoutEl, options) => {
102
103
  scopeOffset,
103
104
  ...calculateOptions,
104
105
  });
105
- if (fullyVisible(tested.styles)) {
106
+ if (fullyVisible(tested)) {
106
107
  calculated = tested;
107
108
  return true;
108
109
  }
@@ -110,7 +111,7 @@ const flyout = (triggerEl, flyoutEl, options) => {
110
111
  });
111
112
  };
112
113
  test(order);
113
- if (!fullyVisible(calculated.styles)) {
114
+ if (!fullyVisible(calculated)) {
114
115
  test(mobileOrder, { fullWidth: true });
115
116
  }
116
117
  }
@@ -125,11 +126,13 @@ const flyoutReducer = (state, action) => {
125
126
  // Disable events before it's positioned to avoid mouseleave getting triggered
126
127
  return { ...state, status: "rendered", styles: { pointerEvents: "none", ...resetStyles } };
127
128
  case "position":
128
- if (state.status !== "rendered")
129
+ if (!action.payload.sync && state.status !== "rendered")
130
+ return state;
131
+ if (action.payload.sync && state.status !== "visible")
129
132
  return state;
130
133
  return {
131
134
  ...state,
132
- status: "positioned",
135
+ status: action.payload.sync ? "visible" : "positioned",
133
136
  position: action.payload.position,
134
137
  styles: { ...defaultStyles, ...action.payload.styles },
135
138
  };
@@ -150,7 +153,7 @@ const flyoutReducer = (state, action) => {
150
153
  }
151
154
  };
152
155
  const useFlyout = (originRef, targetRef, options) => {
153
- const { position: defaultPosition = "bottom", forcePosition, width } = options;
156
+ const { position: defaultPosition = "bottom", forcePosition, width, container } = options;
154
157
  const [isRTL] = useRTL();
155
158
  const [state, dispatch] = React.useReducer(flyoutReducer, {
156
159
  position: defaultPosition,
@@ -169,7 +172,7 @@ const useFlyout = (originRef, targetRef, options) => {
169
172
  const remove = React.useCallback(() => {
170
173
  dispatch({ type: "remove" });
171
174
  }, []);
172
- const updatePosition = React.useCallback(() => {
175
+ const updatePosition = React.useCallback((options) => {
173
176
  if (!originRef.current || !targetRef.current)
174
177
  return;
175
178
  const nextFlyoutData = flyout(originRef.current, targetRef.current, {
@@ -177,9 +180,11 @@ const useFlyout = (originRef, targetRef, options) => {
177
180
  position: defaultPosition,
178
181
  forcePosition,
179
182
  rtl: isRTL,
183
+ container,
180
184
  });
181
- dispatch({ type: "position", payload: nextFlyoutData });
182
- }, [originRef, targetRef, defaultPosition, isRTL, forcePosition, width]);
185
+ if (nextFlyoutData)
186
+ dispatch({ type: "position", payload: { ...nextFlyoutData, sync: options?.sync } });
187
+ }, [container, defaultPosition, forcePosition, isRTL, originRef, targetRef, width]);
183
188
  React.useEffect(() => {
184
189
  if (state.status === "rendered")
185
190
  updatePosition();
@@ -14,5 +14,6 @@ declare const calculatePosition: (args: T.Options & {
14
14
  height: number;
15
15
  };
16
16
  position: T.Position;
17
+ scopeOffset: Record<"left" | "top", number>;
17
18
  };
18
19
  export default calculatePosition;
@@ -33,7 +33,7 @@ const calculatePosition = (args) => {
33
33
  case "start":
34
34
  case "start-top":
35
35
  case "start-bottom":
36
- left = triggerBounds.left - triggerBounds.width;
36
+ left = triggerBounds.left - flyoutBounds.width;
37
37
  break;
38
38
  case "end":
39
39
  case "end-top":
@@ -72,7 +72,7 @@ const calculatePosition = (args) => {
72
72
  break;
73
73
  case "start-bottom":
74
74
  case "end-bottom":
75
- top = triggerBounds.bottom - triggerBounds.height;
75
+ top = triggerBounds.bottom - flyoutBounds.height;
76
76
  break;
77
77
  default:
78
78
  break;
@@ -92,6 +92,6 @@ const calculatePosition = (args) => {
92
92
  widthStyle = triggerBounds.width;
93
93
  }
94
94
  const styles = { left, top, width: widthStyle, height };
95
- return { styles, position };
95
+ return { styles, position, scopeOffset };
96
96
  };
97
97
  export default calculatePosition;
@@ -0,0 +1,8 @@
1
+ declare class Cooldown {
2
+ status: "cold" | "warm" | "cooling";
3
+ timer?: ReturnType<typeof setTimeout>;
4
+ warm: () => void;
5
+ cool: () => void;
6
+ }
7
+ declare const _default: Cooldown;
8
+ export default _default;
@@ -0,0 +1,18 @@
1
+ class Cooldown {
2
+ status = "cold";
3
+ timer;
4
+ warm = () => {
5
+ clearTimeout(this.timer);
6
+ this.status = "warm";
7
+ };
8
+ cool = () => {
9
+ this.status = "cooling";
10
+ const currentTimer = setTimeout(() => {
11
+ this.status = "cold";
12
+ if (currentTimer === this.timer)
13
+ this.timer = undefined;
14
+ }, 2000);
15
+ this.timer = currentTimer;
16
+ };
17
+ }
18
+ export default new Cooldown();
package/dist/index.d.ts CHANGED
@@ -24,7 +24,7 @@ export type { CalendarProps } from "./components/Calendar";
24
24
  export { default as Card } from "./components/Card";
25
25
  export type { CardProps } from "./components/Card";
26
26
  export { default as Carousel } from "./components/Carousel";
27
- export type { CarouselProps, CarouselInstanceRef } from "./components/Carousel";
27
+ export type { CarouselProps, CarouselInstanceRef, CarouselInstance } from "./components/Carousel";
28
28
  export { default as Checkbox } from "./components/Checkbox";
29
29
  export type { CheckboxProps } from "./components/Checkbox";
30
30
  export { default as CheckboxGroup } from "./components/CheckboxGroup";
@@ -36,7 +36,7 @@ export type { DismissibleProps } from "./components/Dismissible";
36
36
  export { default as Divider } from "./components/Divider";
37
37
  export type { DividerProps } from "./components/Divider";
38
38
  export { default as DropdownMenu } from "./components/DropdownMenu";
39
- export type { DropdownMenuProps } from "./components/DropdownMenu";
39
+ export type { DropdownMenuProps, DropdownMenuInstance } from "./components/DropdownMenu";
40
40
  export { default as FileUpload } from "./components/FileUpload";
41
41
  export type { FileUploadProps } from "./components/FileUpload";
42
42
  export { default as FormControl } from "./components/FormControl";
@@ -66,7 +66,7 @@ export type { PaginationProps } from "./components/Pagination";
66
66
  export { default as PinField } from "./components/PinField";
67
67
  export type { PinFieldProps } from "./components/PinField";
68
68
  export { default as Popover } from "./components/Popover";
69
- export type { PopoverProps } from "./components/Popover";
69
+ export type { PopoverProps, PopoverInstance } from "./components/Popover";
70
70
  export { default as Progress } from "./components/Progress";
71
71
  export type { ProgressProps } from "./components/Progress";
72
72
  export { default as Radio } from "./components/Radio";
@@ -0,0 +1 @@
1
+ .root{border:1px solid var(--rs-border-color)}.--border-neutral{--rs-border-color:var(--rs-color-border-neutral)}.--border-neutral-faded{--rs-border-color:var(--rs-color-border-neutral-faded)}.--border-positive{--rs-border-color:var(--rs-color-border-positive)}.--border-positive-faded{--rs-border-color:var(--rs-color-border-positive-faded)}.--border-warning{--rs-border-color:var(--rs-color-border-warning)}.--border-warning-faded{--rs-border-color:var(--rs-color-border-warning-faded)}.--border-critical{--rs-border-color:var(--rs-color-border-critical)}.--border-critical-faded{--rs-border-color:var(--rs-color-border-critical-faded)}.--border-primary{--rs-border-color:var(--rs-color-border-primary)}.--border-primary-faded{--rs-border-color:var(--rs-color-border-primary-faded)}.--border-disabled{--rs-border-color:var(--rs-color-border-disabled)}.--border-brand{--rs-border-color:var(--rs-color-brand)}.--border-transparent{--rs-border-color:transparent}@media (--rs-viewport-m ){.--border-neutral--m{--rs-border-color:var(--rs-color-border-neutral)}.--border-neutral-faded--m{--rs-border-color:var(--rs-color-border-neutral-faded)}.--border-positive--m{--rs-border-color:var(--rs-color-border-positive)}.--border-positive-faded--m{--rs-border-color:var(--rs-color-border-positive-faded)}.--border-warning--m{--rs-border-color:var(--rs-color-border-warning)}.--border-warning-faded--m{--rs-border-color:var(--rs-color-border-warning-faded)}.--border-critical--m{--rs-border-color:var(--rs-color-border-critical)}.--border-critical-faded--m{--rs-border-color:var(--rs-color-border-critical-faded)}.--border-primary--m{--rs-border-color:var(--rs-color-border-primary)}.--border-primary-faded--m{--rs-border-color:var(--rs-color-border-primary-faded)}.--border-disabled--m{--rs-border-color:var(--rs-color-border-disabled)}.--border-brand--m{--rs-border-color:var(--rs-color-brand)}.--border-transparent--m{--rs-border-color:transparent}}@media (--rs-viewport-l ){.--border-neutral--l{--rs-border-color:var(--rs-color-border-neutral)}.--border-neutral-faded--l{--rs-border-color:var(--rs-color-border-neutral-faded)}.--border-positive--l{--rs-border-color:var(--rs-color-border-positive)}.--border-positive-faded--l{--rs-border-color:var(--rs-color-border-positive-faded)}.--border-warning--l{--rs-border-color:var(--rs-color-border-warning)}.--border-warning-faded--l{--rs-border-color:var(--rs-color-border-warning-faded)}.--border-critical--l{--rs-border-color:var(--rs-color-border-critical)}.--border-critical-faded--l{--rs-border-color:var(--rs-color-border-critical-faded)}.--border-primary--l{--rs-border-color:var(--rs-color-border-primary)}.--border-primary-faded--l{--rs-border-color:var(--rs-color-border-primary-faded)}.--border-disabled--l{--rs-border-color:var(--rs-color-border-disabled)}.--border-brand--l{--rs-border-color:var(--rs-color-brand)}.--border-transparent--l{--rs-border-color:transparent}}@media (--rs-viewport-xl ){.--border-neutral--xl{--rs-border-color:var(--rs-color-border-neutral)}.--border-neutral-faded--xl{--rs-border-color:var(--rs-color-border-neutral-faded)}.--border-positive--xl{--rs-border-color:var(--rs-color-border-positive)}.--border-positive-faded--xl{--rs-border-color:var(--rs-color-border-positive-faded)}.--border-warning--xl{--rs-border-color:var(--rs-color-border-warning)}.--border-warning-faded--xl{--rs-border-color:var(--rs-color-border-warning-faded)}.--border-critical--xl{--rs-border-color:var(--rs-color-border-critical)}.--border-critical-faded--xl{--rs-border-color:var(--rs-color-border-critical-faded)}.--border-primary--xl{--rs-border-color:var(--rs-color-border-primary)}.--border-primary-faded--xl{--rs-border-color:var(--rs-color-border-primary-faded)}.--border-disabled--xl{--rs-border-color:var(--rs-color-border-disabled)}.--border-brand--xl{--rs-border-color:var(--rs-color-brand)}.--border-transparent--xl{--rs-border-color:transparent}}
@@ -0,0 +1,3 @@
1
+ import * as T from "../types";
2
+ declare const getBorderStyles: T.StaticStyleUtility<T.BorderColor>;
3
+ export default getBorderStyles;
@@ -0,0 +1,10 @@
1
+ import { responsiveClassNames } from "../../utilities/helpers.js";
2
+ import s from "./border.module.css";
3
+ const getBorderStyles = (value) => {
4
+ if (!value)
5
+ return null;
6
+ return {
7
+ classNames: [s.root, ...responsiveClassNames(s, "--border", value)],
8
+ };
9
+ };
10
+ export default getBorderStyles;
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import * as G from "../types/global";
3
3
  export type Radius = "small" | "medium" | "large" | "circular" | "none";
4
4
  export type Position = "relative" | "absolute" | "fixed" | "sticky" | "static";
5
+ export type BorderColor = "neutral" | "neutral-faded" | "critical" | "critical-faded" | "warning" | "warning-faded" | "positive" | "positive-faded" | "primary" | "primary-faded" | "disabled" | "brand" | "transparent";
5
6
  /**
6
7
  * Utility controlled only with classnames
7
8
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reshaped",
3
3
  "description": "Professionally crafted design system in React & Figma for building products of any scale and complexity",
4
- "version": "3.0.3",
4
+ "version": "3.0.4",
5
5
  "license": "MIT",
6
6
  "email": "hello@reshaped.so",
7
7
  "homepage": "https://reshaped.so",
@@ -1,2 +0,0 @@
1
- export declare const mouseEnter = 100;
2
- export declare const mouseLeave = 150;
@@ -1,2 +0,0 @@
1
- export const mouseEnter = 100;
2
- export const mouseLeave = 150;