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.
- package/CHANGELOG.md +14 -1
- package/dist/bundle.css +1 -1
- package/dist/bundle.d.ts +3 -3
- package/dist/bundle.js +10 -10
- package/dist/components/Autocomplete/Autocomplete.js +2 -2
- package/dist/components/Autocomplete/Autocomplete.types.d.ts +2 -1
- package/dist/components/Carousel/Carousel.types.d.ts +2 -2
- package/dist/components/Carousel/index.d.ts +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.types.d.ts +3 -2
- package/dist/components/DropdownMenu/index.d.ts +1 -1
- package/dist/components/Modal/Modal.js +9 -4
- package/dist/components/Popover/Popover.js +2 -2
- package/dist/components/Popover/Popover.types.d.ts +3 -2
- package/dist/components/Popover/index.d.ts +1 -1
- package/dist/components/Text/Text.js +1 -1
- package/dist/components/Text/Text.module.css +1 -1
- package/dist/components/Text/Text.types.d.ts +1 -1
- package/dist/components/Text/tests/Text.stories.js +3 -0
- package/dist/components/Tooltip/Tooltip.js +2 -2
- package/dist/components/Tooltip/Tooltip.types.d.ts +1 -1
- package/dist/components/Tooltip/tests/Tooltip.stories.js +25 -1
- package/dist/components/View/View.js +3 -1
- package/dist/components/View/View.module.css +1 -1
- package/dist/components/View/View.types.d.ts +1 -1
- package/dist/components/View/tests/View.stories.js +6 -0
- package/dist/components/_private/Flyout/Flyout.constants.d.ts +3 -0
- package/dist/components/_private/Flyout/Flyout.constants.js +3 -0
- package/dist/components/_private/Flyout/Flyout.module.css +1 -1
- package/dist/components/_private/Flyout/Flyout.types.d.ts +9 -3
- package/dist/components/_private/Flyout/FlyoutContent.js +7 -4
- package/dist/components/_private/Flyout/FlyoutControlled.js +33 -18
- package/dist/components/_private/Flyout/index.d.ts +1 -1
- package/dist/components/_private/Flyout/tests/Flyout.stories.d.ts +3 -0
- package/dist/components/_private/Flyout/tests/Flyout.stories.js +62 -0
- package/dist/components/_private/Flyout/useFlyout.d.ts +4 -1
- package/dist/components/_private/Flyout/useFlyout.js +21 -16
- package/dist/components/_private/Flyout/utilities/calculatePosition.d.ts +1 -0
- package/dist/components/_private/Flyout/utilities/calculatePosition.js +3 -3
- package/dist/components/_private/Flyout/utilities/cooldown.d.ts +8 -0
- package/dist/components/_private/Flyout/utilities/cooldown.js +18 -0
- package/dist/index.d.ts +3 -3
- package/dist/styles/border/border.module.css +1 -0
- package/dist/styles/border/index.d.ts +3 -0
- package/dist/styles/border/index.js +10 -0
- package/dist/styles/types.d.ts +1 -0
- package/package.json +1 -1
- package/dist/constants/timeouts.d.ts +0 -2
- 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
|
-
|
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
|
-
*
|
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() &&
|
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
|
197
|
-
|
198
|
-
|
199
|
-
|
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
|
-
|
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,
|
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: (
|
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 = (
|
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 (
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
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
|
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
|
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
|
-
|
182
|
-
|
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();
|
@@ -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 -
|
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 -
|
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,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,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;
|
package/dist/styles/types.d.ts
CHANGED
@@ -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.
|
4
|
+
"version": "3.0.4",
|
5
5
|
"license": "MIT",
|
6
6
|
"email": "hello@reshaped.so",
|
7
7
|
"homepage": "https://reshaped.so",
|