reshaped 3.2.0-canary.6 → 3.2.0-canary.7
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 +25 -2
- package/dist/bundle.css +1 -1
- package/dist/bundle.d.ts +2 -0
- package/dist/bundle.js +11 -12
- package/dist/cjs/constants/breakpoints.d.ts +6 -0
- package/dist/cjs/constants/breakpoints.js +7 -0
- package/dist/cjs/themes/_generator/definitions/reshaped.js +8 -4
- package/dist/cjs/themes/_generator/tokens/viewport/viewport.transforms.js +10 -1
- package/dist/cjs/themes/figma/theme.css +1 -1
- package/dist/cjs/themes/reshaped/theme.css +1 -1
- package/dist/cjs/themes/slate/theme.css +1 -1
- package/dist/components/Actionable/Actionable.d.ts +1 -1
- package/dist/components/Actionable/Actionable.module.css +1 -1
- package/dist/components/Autocomplete/Autocomplete.js +2 -2
- package/dist/components/Button/Button.js +1 -1
- package/dist/components/Button/Button.module.css +1 -1
- package/dist/components/Card/Card.d.ts +1 -1
- package/dist/components/Card/Card.module.css +1 -1
- package/dist/components/Card/tests/Card.stories.d.ts +1 -1
- package/dist/components/Checkbox/Checkbox.module.css +1 -1
- package/dist/components/Divider/Divider.js +4 -3
- package/dist/components/Divider/Divider.module.css +1 -1
- package/dist/components/Divider/Divider.types.d.ts +3 -0
- package/dist/components/Divider/tests/Divider.stories.d.ts +1 -0
- package/dist/components/Divider/tests/Divider.stories.js +21 -0
- package/dist/components/DropdownMenu/DropdownMenu.types.d.ts +1 -1
- package/dist/components/FormControl/FormControl.context.d.ts +2 -1
- package/dist/components/Grid/Grid.d.ts +6 -0
- package/dist/components/Grid/Grid.js +46 -0
- package/dist/components/Grid/Grid.module.css +1 -0
- package/dist/components/Grid/Grid.types.d.ts +31 -0
- package/dist/components/Grid/Grid.types.js +1 -0
- package/dist/components/Grid/index.d.ts +2 -0
- package/dist/components/Grid/index.js +1 -0
- package/dist/components/Grid/tests/Grid.stories.d.ts +18 -0
- package/dist/components/Grid/tests/Grid.stories.js +170 -0
- package/dist/components/Icon/Icon.module.css +1 -1
- package/dist/components/Link/Link.d.ts +1 -1
- package/dist/components/Link/tests/Link.stories.d.ts +1 -1
- package/dist/components/Loader/Loader.module.css +1 -1
- package/dist/components/Loader/Loader.types.d.ts +1 -1
- package/dist/components/Loader/tests/Loader.stories.js +5 -3
- package/dist/components/Modal/Modal.js +7 -4
- package/dist/components/Modal/Modal.module.css +1 -1
- package/dist/components/Modal/Modal.types.d.ts +1 -1
- package/dist/components/Modal/tests/Modal.stories.d.ts +1 -0
- package/dist/components/Modal/tests/Modal.stories.js +28 -1
- package/dist/components/Overlay/Overlay.js +45 -27
- package/dist/components/Overlay/Overlay.module.css +1 -1
- package/dist/components/Overlay/Overlay.types.d.ts +1 -0
- package/dist/components/Popover/Popover.js +2 -4
- package/dist/components/Popover/Popover.types.d.ts +1 -1
- package/dist/components/Radio/Radio.module.css +1 -1
- package/dist/components/Resizable/Resizable.module.css +1 -1
- package/dist/components/ScrollArea/ScrollArea.js +1 -1
- package/dist/components/Slider/Slider.module.css +1 -1
- package/dist/components/Slider/SliderControlled.js +2 -1
- package/dist/components/Switch/Switch.module.css +1 -1
- package/dist/components/Tabs/Tabs.d.ts +1 -1
- package/dist/components/Tabs/Tabs.module.css +1 -1
- package/dist/components/Tabs/TabsContext.d.ts +1 -1
- package/dist/components/Tabs/TabsItem.d.ts +1 -1
- package/dist/components/Tabs/TabsItem.js +2 -3
- package/dist/components/Tabs/TabsList.js +1 -1
- package/dist/components/Tabs/tests/Tabs.stories.d.ts +15 -13
- package/dist/components/Tabs/tests/Tabs.stories.js +71 -8
- package/dist/components/TextField/TextField.js +5 -1
- package/dist/components/TextField/TextField.module.css +1 -1
- package/dist/components/TextField/tests/TextField.stories.js +4 -0
- package/dist/components/Toast/ToastContainer.js +1 -2
- package/dist/components/Toast/ToastRegion.js +1 -1
- package/dist/components/View/View.js +7 -3
- package/dist/components/View/View.module.css +1 -1
- package/dist/components/View/View.types.d.ts +2 -2
- package/dist/components/_private/Flyout/Flyout.module.css +1 -1
- package/dist/components/_private/Flyout/Flyout.types.d.ts +11 -3
- package/dist/components/_private/Flyout/FlyoutContent.js +1 -1
- package/dist/components/_private/Flyout/FlyoutControlled.js +25 -15
- package/dist/components/_private/Flyout/tests/Flyout.stories.d.ts +3 -1
- package/dist/components/_private/Flyout/tests/Flyout.stories.js +54 -32
- package/dist/components/_private/Flyout/useFlyout.d.ts +2 -1
- package/dist/components/_private/Flyout/useFlyout.js +45 -55
- package/dist/components/_private/Flyout/utilities/calculatePosition.js +16 -11
- package/dist/components/_private/Flyout/utilities/getPositionFallbacks.d.ts +3 -0
- package/dist/components/_private/Flyout/utilities/getPositionFallbacks.js +39 -0
- package/dist/config/tailwind.d.ts +1 -1
- package/dist/constants/breakpoints.d.ts +6 -0
- package/dist/constants/breakpoints.js +5 -0
- package/dist/hooks/_private/useIsDismissible.js +7 -14
- package/dist/hooks/_private/useSingletonKeyboardMode.js +1 -1
- package/dist/hooks/tests/useResponsiveClientValue.stories.d.ts +1 -2
- package/dist/hooks/tests/useResponsiveClientValue.stories.js +1 -2
- package/dist/hooks/useDrag.js +2 -1
- package/dist/hooks/useResponsiveClientValue.js +22 -11
- package/dist/hooks/useScrollLock.d.ts +4 -1
- package/dist/hooks/useScrollLock.js +14 -40
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/styles/align/align.module.css +1 -0
- package/dist/styles/align/index.d.ts +3 -0
- package/dist/styles/align/index.js +10 -0
- package/dist/styles/justify/index.d.ts +3 -0
- package/dist/styles/justify/index.js +10 -0
- package/dist/styles/justify/justify.module.css +1 -0
- package/dist/styles/types.d.ts +2 -0
- package/dist/themes/_generator/definitions/reshaped.js +5 -4
- package/dist/themes/_generator/tokens/viewport/viewport.transforms.js +10 -1
- package/dist/themes/figma/theme.css +1 -1
- package/dist/themes/reshaped/theme.css +1 -1
- package/dist/themes/slate/theme.css +1 -1
- package/dist/utilities/a11y/TrapFocus.d.ts +1 -1
- package/dist/utilities/a11y/TrapFocus.js +1 -1
- package/dist/utilities/a11y/focus.js +1 -1
- package/dist/utilities/a11y/index.d.ts +4 -0
- package/dist/utilities/a11y/index.js +3 -0
- package/dist/utilities/css.d.ts +7 -0
- package/dist/utilities/css.js +18 -0
- package/dist/utilities/dom/flyout.d.ts +1 -0
- package/dist/utilities/{dom.js → dom/flyout.js} +1 -19
- package/dist/utilities/dom/index.d.ts +3 -0
- package/dist/utilities/dom/index.js +3 -0
- package/dist/utilities/dom/shadowDom.d.ts +1 -0
- package/dist/utilities/dom/shadowDom.js +4 -0
- package/dist/utilities/dom/userSelect.d.ts +2 -0
- package/dist/utilities/dom/userSelect.js +6 -0
- package/dist/utilities/platform.d.ts +1 -0
- package/dist/utilities/platform.js +15 -0
- package/dist/utilities/scroll/disable.d.ts +7 -0
- package/dist/utilities/scroll/disable.js +13 -0
- package/dist/utilities/scroll/helpers.d.ts +1 -0
- package/dist/utilities/scroll/helpers.js +17 -0
- package/dist/utilities/scroll/index.d.ts +2 -0
- package/dist/utilities/scroll/index.js +2 -0
- package/dist/utilities/scroll/lock.d.ts +5 -0
- package/dist/utilities/scroll/lock.js +24 -0
- package/dist/utilities/scroll/lockSafari.d.ts +2 -0
- package/dist/utilities/scroll/lockSafari.js +21 -0
- package/dist/utilities/scroll/lockStandard.d.ts +2 -0
- package/dist/utilities/scroll/lockStandard.js +17 -0
- package/dist/utilities/storybook/Placeholder.d.ts +1 -0
- package/dist/utilities/storybook/Placeholder.js +2 -2
- package/package.json +45 -48
- package/dist/utilities/dom.d.ts +0 -6
@@ -1,25 +1,8 @@
|
|
1
1
|
import React from "react";
|
2
2
|
import useRTL from "../../../hooks/useRTL.js";
|
3
|
-
import { getClosestFlyoutTarget, getShadowRoot } from "../../../utilities/dom.js";
|
3
|
+
import { getClosestFlyoutTarget, getShadowRoot } from "../../../utilities/dom/index.js";
|
4
4
|
import calculatePosition from "./utilities/calculatePosition.js";
|
5
|
-
|
6
|
-
const bottomPos = ["bottom-start", "bottom", "bottom-end"];
|
7
|
-
const startPos = ["start", "start-bottom", "start-top"];
|
8
|
-
const endPos = ["end", "end-bottom", "end-top"];
|
9
|
-
const order = {
|
10
|
-
top: [...topPos, ...bottomPos, ...endPos, ...startPos],
|
11
|
-
bottom: [...bottomPos, ...topPos, ...endPos, ...startPos],
|
12
|
-
start: [...startPos, ...endPos, ...topPos, ...bottomPos],
|
13
|
-
end: [...endPos, ...startPos, ...topPos, ...bottomPos],
|
14
|
-
};
|
15
|
-
/**
|
16
|
-
* Get an order of positions to try to fit popover on the screen based on its starting position
|
17
|
-
*/
|
18
|
-
const getPositionOrder = (position) => {
|
19
|
-
const types = ["top", "bottom", "start", "end"];
|
20
|
-
const type = types.find((type) => position.startsWith(type)) || "bottom";
|
21
|
-
return order[type];
|
22
|
-
};
|
5
|
+
import getPositionFallbacks from "./utilities/getPositionFallbacks.js";
|
23
6
|
/**
|
24
7
|
* Check if element visually fits on the screen
|
25
8
|
*/
|
@@ -60,12 +43,13 @@ const resetStyles = {
|
|
60
43
|
* Set position of the target element to fit on the screen
|
61
44
|
*/
|
62
45
|
const flyout = (args) => {
|
63
|
-
const { triggerEl, flyoutEl, triggerBounds: passedTriggerBounds, ...options } = args;
|
64
|
-
const { position,
|
46
|
+
const { triggerEl, flyoutEl, triggerBounds: passedTriggerBounds, contentGap = 0, ...options } = args;
|
47
|
+
const { position, fallbackPositions, width, container, lastUsedFallback, onFallback } = options;
|
65
48
|
const targetClone = flyoutEl.cloneNode(true);
|
66
49
|
const triggerBounds = passedTriggerBounds || triggerEl.getBoundingClientRect();
|
50
|
+
const contentGapModifier = parseInt(getComputedStyle(flyoutEl).getPropertyValue("--rs-unit-x1"));
|
67
51
|
// Reset all styles applied on the previous hook execution
|
68
|
-
targetClone.style = "";
|
52
|
+
targetClone.style.cssText = "";
|
69
53
|
Object.keys(resetStyles).forEach((key) => {
|
70
54
|
const value = resetStyles[key];
|
71
55
|
targetClone.style[key] = value.toString();
|
@@ -88,37 +72,30 @@ const flyout = (args) => {
|
|
88
72
|
top: containerBounds.top + document.documentElement.scrollTop - containerParent.scrollTop,
|
89
73
|
left: containerBounds.left + document.documentElement.scrollLeft - containerParent.scrollLeft,
|
90
74
|
};
|
91
|
-
let calculated =
|
92
|
-
|
93
|
-
|
94
|
-
const
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
});
|
109
|
-
if (fullyVisible(tested)) {
|
110
|
-
calculated = tested;
|
111
|
-
return true;
|
112
|
-
}
|
113
|
-
return false;
|
114
|
-
});
|
115
|
-
};
|
116
|
-
test(order);
|
117
|
-
if (!fullyVisible(calculated)) {
|
118
|
-
test(mobileOrder, { fullWidth: true });
|
75
|
+
let calculated = null;
|
76
|
+
const testOrder = getPositionFallbacks(position, fallbackPositions);
|
77
|
+
testOrder.some((currentPosition, index) => {
|
78
|
+
const tested = calculatePosition({
|
79
|
+
...options,
|
80
|
+
triggerBounds,
|
81
|
+
flyoutBounds,
|
82
|
+
scopeOffset,
|
83
|
+
position: currentPosition,
|
84
|
+
contentGap: contentGap * contentGapModifier,
|
85
|
+
});
|
86
|
+
const visible = fullyVisible(tested);
|
87
|
+
const validPosition = visible || fallbackPositions?.length === 0;
|
88
|
+
// Saving first try in case non of the options work
|
89
|
+
if (validPosition || lastUsedFallback === currentPosition) {
|
90
|
+
calculated = tested;
|
91
|
+
onFallback(currentPosition);
|
119
92
|
}
|
93
|
+
return validPosition;
|
94
|
+
});
|
95
|
+
if (!calculated) {
|
96
|
+
throw new Error(`Reshaped: Can't calculate styles for the ${position} position`);
|
120
97
|
}
|
121
|
-
targetClone.parentNode
|
98
|
+
targetClone.parentNode?.removeChild(targetClone);
|
122
99
|
return calculated;
|
123
100
|
};
|
124
101
|
const flyoutReducer = (state, action) => {
|
@@ -156,8 +133,13 @@ const flyoutReducer = (state, action) => {
|
|
156
133
|
}
|
157
134
|
};
|
158
135
|
const useFlyout = (args) => {
|
159
|
-
const { triggerElRef, flyoutElRef, triggerBoundsRef, ...options } = args;
|
160
|
-
const { position: defaultPosition = "bottom",
|
136
|
+
const { triggerElRef, flyoutElRef, triggerBoundsRef, contentGap, ...options } = args;
|
137
|
+
const { position: defaultPosition = "bottom", fallbackPositions, width, container } = options;
|
138
|
+
const lastUsedFallbackRef = React.useRef(defaultPosition);
|
139
|
+
// Memo the array internally to avoid new arrays triggering useCallback
|
140
|
+
const cachedFallbackPositions = React.useMemo(() => fallbackPositions,
|
141
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
142
|
+
[fallbackPositions?.join(" ")]);
|
161
143
|
const [isRTL] = useRTL();
|
162
144
|
const [state, dispatch] = React.useReducer(flyoutReducer, {
|
163
145
|
position: defaultPosition,
|
@@ -176,6 +158,9 @@ const useFlyout = (args) => {
|
|
176
158
|
const remove = React.useCallback(() => {
|
177
159
|
dispatch({ type: "remove" });
|
178
160
|
}, []);
|
161
|
+
const handleFallback = React.useCallback((position) => {
|
162
|
+
lastUsedFallbackRef.current = position;
|
163
|
+
}, []);
|
179
164
|
const updatePosition = React.useCallback((options) => {
|
180
165
|
if (!triggerElRef.current || !flyoutElRef.current)
|
181
166
|
return;
|
@@ -185,21 +170,26 @@ const useFlyout = (args) => {
|
|
185
170
|
triggerBounds: triggerBoundsRef.current,
|
186
171
|
width,
|
187
172
|
position: defaultPosition,
|
188
|
-
|
173
|
+
fallbackPositions: cachedFallbackPositions,
|
174
|
+
lastUsedFallback: lastUsedFallbackRef.current,
|
175
|
+
onFallback: handleFallback,
|
189
176
|
rtl: isRTL,
|
190
177
|
container,
|
178
|
+
contentGap,
|
191
179
|
});
|
192
180
|
if (nextFlyoutData)
|
193
181
|
dispatch({ type: "position", payload: { ...nextFlyoutData, sync: options?.sync } });
|
194
182
|
}, [
|
195
183
|
container,
|
196
184
|
defaultPosition,
|
197
|
-
|
185
|
+
cachedFallbackPositions,
|
198
186
|
isRTL,
|
199
187
|
flyoutElRef,
|
200
188
|
triggerElRef,
|
201
189
|
triggerBoundsRef,
|
202
190
|
width,
|
191
|
+
contentGap,
|
192
|
+
handleFallback,
|
203
193
|
]);
|
204
194
|
React.useEffect(() => {
|
205
195
|
if (state.status === "rendered")
|
@@ -16,24 +16,29 @@ const centerBySize = (originSize, targetSize) => {
|
|
16
16
|
* Calculate styles for the current position
|
17
17
|
*/
|
18
18
|
const calculatePosition = (args) => {
|
19
|
-
const { triggerBounds, flyoutBounds, scopeOffset, position: passedPosition, rtl, width } = args;
|
19
|
+
const { triggerBounds, flyoutBounds, scopeOffset, position: passedPosition, rtl, width, contentGap = 0, } = args;
|
20
|
+
const isFullWidth = width === "full" || width === "100%";
|
20
21
|
let left = 0;
|
21
22
|
let top = 0;
|
22
23
|
let position = passedPosition;
|
23
24
|
if (rtl)
|
24
25
|
position = getRTLPosition(position);
|
25
|
-
if (
|
26
|
+
if (isFullWidth || width === "trigger") {
|
26
27
|
position = position.includes("top") ? "top" : "bottom";
|
27
28
|
}
|
29
|
+
const isHorizontalPosition = position.match(/^(start|end)/);
|
30
|
+
const isVerticalPosition = position.match(/^(top|bottom)/);
|
31
|
+
const flyoutWidth = flyoutBounds.width + (isHorizontalPosition ? contentGap : 0);
|
32
|
+
const flyoutHeight = flyoutBounds.height + (isVerticalPosition ? contentGap : 0);
|
28
33
|
switch (position) {
|
29
34
|
case "bottom":
|
30
35
|
case "top":
|
31
|
-
left = centerBySize(triggerBounds.width,
|
36
|
+
left = centerBySize(triggerBounds.width, flyoutWidth) + triggerBounds.left;
|
32
37
|
break;
|
33
38
|
case "start":
|
34
39
|
case "start-top":
|
35
40
|
case "start-bottom":
|
36
|
-
left = triggerBounds.left -
|
41
|
+
left = triggerBounds.left - flyoutWidth;
|
37
42
|
break;
|
38
43
|
case "end":
|
39
44
|
case "end-top":
|
@@ -46,7 +51,7 @@ const calculatePosition = (args) => {
|
|
46
51
|
break;
|
47
52
|
case "top-end":
|
48
53
|
case "bottom-end":
|
49
|
-
left = triggerBounds.right -
|
54
|
+
left = triggerBounds.right - flyoutWidth;
|
50
55
|
break;
|
51
56
|
default:
|
52
57
|
break;
|
@@ -55,7 +60,7 @@ const calculatePosition = (args) => {
|
|
55
60
|
case "top":
|
56
61
|
case "top-start":
|
57
62
|
case "top-end":
|
58
|
-
top = triggerBounds.top -
|
63
|
+
top = triggerBounds.top - flyoutHeight;
|
59
64
|
break;
|
60
65
|
case "bottom":
|
61
66
|
case "bottom-start":
|
@@ -64,7 +69,7 @@ const calculatePosition = (args) => {
|
|
64
69
|
break;
|
65
70
|
case "start":
|
66
71
|
case "end":
|
67
|
-
top = centerBySize(triggerBounds.height,
|
72
|
+
top = centerBySize(triggerBounds.height, flyoutHeight) + triggerBounds.top;
|
68
73
|
break;
|
69
74
|
case "start-top":
|
70
75
|
case "end-top":
|
@@ -72,7 +77,7 @@ const calculatePosition = (args) => {
|
|
72
77
|
break;
|
73
78
|
case "start-bottom":
|
74
79
|
case "end-bottom":
|
75
|
-
top = triggerBounds.bottom -
|
80
|
+
top = triggerBounds.bottom - flyoutHeight;
|
76
81
|
break;
|
77
82
|
default:
|
78
83
|
break;
|
@@ -82,9 +87,9 @@ const calculatePosition = (args) => {
|
|
82
87
|
}
|
83
88
|
top = Math.round(top + (window.scrollY || 0) - scopeOffset.top);
|
84
89
|
left = Math.round(left + (window.scrollX || 0) - scopeOffset.left);
|
85
|
-
let widthStyle = Math.ceil(
|
86
|
-
const height = Math.ceil(
|
87
|
-
if (
|
90
|
+
let widthStyle = Math.ceil(flyoutWidth);
|
91
|
+
const height = Math.ceil(flyoutHeight);
|
92
|
+
if (isFullWidth) {
|
88
93
|
left = SCREEN_OFFSET;
|
89
94
|
widthStyle = window.innerWidth - SCREEN_OFFSET * 2;
|
90
95
|
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
// All available positions for each side
|
2
|
+
const positions = {
|
3
|
+
top: ["top-start", "top-end", "top"],
|
4
|
+
bottom: ["bottom-start", "bottom-end", "bottom"],
|
5
|
+
start: ["start-top", "start-bottom", "start"],
|
6
|
+
end: ["end-top", "end-bottom", "end"],
|
7
|
+
};
|
8
|
+
// Order of sides to try depending on the starting side
|
9
|
+
const fallbackOrder = {
|
10
|
+
top: ["bottom", "start", "end"],
|
11
|
+
bottom: ["top", "end", "start"],
|
12
|
+
start: ["end", "top", "bottom"],
|
13
|
+
end: ["start", "bottom", "top"],
|
14
|
+
};
|
15
|
+
// Get an order of positions to try to fit flyout on the screen based on its starting position
|
16
|
+
const getPositionFallbacks = (position, availableFallbacks) => {
|
17
|
+
const result = [position];
|
18
|
+
const chunks = position.split("-");
|
19
|
+
const [firstChunk] = chunks;
|
20
|
+
const passedPositionOrder = positions[firstChunk];
|
21
|
+
const startingFallbackIndex = passedPositionOrder.indexOf(position);
|
22
|
+
const fallbackIndexOrder = [startingFallbackIndex];
|
23
|
+
passedPositionOrder.forEach((_, index) => {
|
24
|
+
if (index === startingFallbackIndex)
|
25
|
+
return;
|
26
|
+
fallbackIndexOrder.push(index);
|
27
|
+
});
|
28
|
+
[firstChunk, ...fallbackOrder[firstChunk]].forEach((fallbackSide) => {
|
29
|
+
const fallbackOrder = positions[fallbackSide];
|
30
|
+
fallbackIndexOrder.forEach((index) => {
|
31
|
+
const position = fallbackOrder[index];
|
32
|
+
if (availableFallbacks?.indexOf(position) === -1)
|
33
|
+
return;
|
34
|
+
result.push(position);
|
35
|
+
});
|
36
|
+
});
|
37
|
+
return result;
|
38
|
+
};
|
39
|
+
export default getPositionFallbacks;
|
@@ -1,2 +1,2 @@
|
|
1
1
|
import type { ThemeDefinition } from "../themes/_generator/tokens/types";
|
2
|
-
export declare const getTheme: (theme?: ThemeDefinition) => Record<"borderRadius" | "backgroundColor" | "borderColor" | "
|
2
|
+
export declare const getTheme: (theme?: ThemeDefinition) => Record<"borderRadius" | "backgroundColor" | "borderColor" | "boxShadow" | "textColor" | "colors" | "spacing" | "screens", Record<string, string>>;
|
@@ -18,26 +18,19 @@ const removeFromQueue = (id) => {
|
|
18
18
|
queue = {};
|
19
19
|
};
|
20
20
|
const addToQueue = (id, contentRef, triggerRef) => {
|
21
|
-
const parentItem = latestId ? queue[latestId] : undefined;
|
22
|
-
const insideParent = triggerRef?.current &&
|
23
|
-
parentItem &&
|
24
|
-
parentItem.contentRef.current?.contains(triggerRef.current);
|
25
|
-
if (!insideParent && triggerRef && latestId) {
|
26
|
-
removeFromQueue(latestId);
|
27
|
-
}
|
28
21
|
queue[id] = { parentId: latestId, triggerRef, contentRef };
|
29
22
|
latestId = id;
|
30
23
|
};
|
31
24
|
const useIsDismissible = (active = false, contentRef, triggerRef) => {
|
32
25
|
const id = useElementId();
|
33
|
-
const isDismissible = React.useCallback(() =>
|
26
|
+
const isDismissible = React.useCallback(() => {
|
27
|
+
return active ? latestId === id : true;
|
28
|
+
}, [id, active]);
|
34
29
|
React.useEffect(() => {
|
35
|
-
if (active)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
removeFromQueue(id);
|
40
|
-
}
|
30
|
+
if (!active)
|
31
|
+
return;
|
32
|
+
addToQueue(id, contentRef, triggerRef);
|
33
|
+
return () => removeFromQueue(id);
|
41
34
|
}, [active, id, contentRef, triggerRef]);
|
42
35
|
return isDismissible;
|
43
36
|
};
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import React from "react";
|
2
|
-
import { enableKeyboardMode, disableKeyboardMode } from "../../utilities/a11y/
|
2
|
+
import { enableKeyboardMode, disableKeyboardMode } from "../../utilities/a11y/index.js";
|
3
3
|
const useSingletonKeyboardMode = () => {
|
4
4
|
React.useEffect(() => {
|
5
5
|
const handleKeyDown = (e) => {
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import React from "react";
|
2
1
|
import useResponsiveClientValue from "../useResponsiveClientValue.js";
|
3
2
|
import View from "../../components/View/index.js";
|
4
3
|
export default { title: "Hooks/useResponsiveClientValue" };
|
@@ -10,4 +9,4 @@ function Example() {
|
|
10
9
|
});
|
11
10
|
return <View width={25} height={25} backgroundColor={value}/>;
|
12
11
|
}
|
13
|
-
export const
|
12
|
+
export const base = () => <Example />;
|
package/dist/hooks/useDrag.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"use client";
|
2
2
|
import React from "react";
|
3
|
-
import { disableUserSelect, enableUserSelect
|
3
|
+
import { disableUserSelect, enableUserSelect } from "../utilities/dom/index.js";
|
4
|
+
import { disableScroll, enableScroll } from "../utilities/scroll/index.js";
|
4
5
|
import useToggle from "./useToggle.js";
|
5
6
|
import useHotkeys from "./useHotkeys.js";
|
6
7
|
import * as keys from "../constants/keys.js";
|
@@ -2,21 +2,32 @@
|
|
2
2
|
import React from "react";
|
3
3
|
import { SingletonEnvironmentContext } from "./_private/useSingletonEnvironment.js";
|
4
4
|
import useIsomorphicLayoutEffect from "./useIsomorphicLayoutEffect.js";
|
5
|
-
|
6
|
-
m: 660,
|
7
|
-
l: 900,
|
8
|
-
xl: 1280,
|
9
|
-
};
|
10
|
-
const mediaQueries = {
|
11
|
-
s: `(max-width: ${breakpoints.m - 1}px)`,
|
12
|
-
m: `(min-width: ${breakpoints.m}px) and (max-width: ${breakpoints.l - 1}px)`,
|
13
|
-
l: `(min-width: ${breakpoints.l}px) and (max-width: ${breakpoints.xl - 1}px)`,
|
14
|
-
xl: `(min-width: ${breakpoints.xl}px)`,
|
15
|
-
};
|
5
|
+
import defaultBreakpoints from "../constants/breakpoints.js";
|
16
6
|
const useResponsiveClientValue = (value) => {
|
17
7
|
const { defaultViewport } = React.useContext(SingletonEnvironmentContext);
|
18
8
|
const [viewport, setViewport] = React.useState(defaultViewport);
|
19
9
|
useIsomorphicLayoutEffect(() => {
|
10
|
+
const rootThemeEl = document.querySelector("[data-rs-theme]");
|
11
|
+
const rootStyle = rootThemeEl && window.getComputedStyle(rootThemeEl);
|
12
|
+
/**
|
13
|
+
* We generate variables for the viewport breakpoints in the themes
|
14
|
+
* We use them here in case they're custom and fallback to the default values
|
15
|
+
* in case there is no SSR passing the data-rs-theme attribute
|
16
|
+
*/
|
17
|
+
const breakpoints = {
|
18
|
+
m: (rootStyle && Number(rootStyle.getPropertyValue("--rs-viewport-m-min"))) ||
|
19
|
+
defaultBreakpoints.m,
|
20
|
+
l: (rootStyle && Number(rootStyle.getPropertyValue("--rs-viewport-l-min"))) ||
|
21
|
+
defaultBreakpoints.l,
|
22
|
+
xl: (rootStyle && Number(rootStyle.getPropertyValue("--rs-viewport-xl-min"))) ||
|
23
|
+
defaultBreakpoints.xl,
|
24
|
+
};
|
25
|
+
const mediaQueries = {
|
26
|
+
s: `(max-width: ${breakpoints.m - 1}px)`,
|
27
|
+
m: `(min-width: ${breakpoints.m}px) and (max-width: ${breakpoints.l - 1}px)`,
|
28
|
+
l: `(min-width: ${breakpoints.l}px) and (max-width: ${breakpoints.xl - 1}px)`,
|
29
|
+
xl: `(min-width: ${breakpoints.xl}px)`,
|
30
|
+
};
|
20
31
|
const viewports = Object.keys(mediaQueries);
|
21
32
|
const matchers = viewports.map((viewport) => {
|
22
33
|
const mq = window.matchMedia(mediaQueries[viewport]);
|
@@ -1,45 +1,19 @@
|
|
1
1
|
"use client";
|
2
2
|
import React from "react";
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
if (scrollbarWidth)
|
7
|
-
return scrollbarWidth;
|
8
|
-
const scrollDiv = document.createElement("div");
|
9
|
-
scrollDiv.style.position = "absolute";
|
10
|
-
scrollDiv.style.top = "-9999px";
|
11
|
-
scrollDiv.style.width = "50px";
|
12
|
-
scrollDiv.style.height = "50px";
|
13
|
-
scrollDiv.style.overflow = "scroll";
|
14
|
-
document.body.appendChild(scrollDiv);
|
15
|
-
scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
|
16
|
-
document.body.removeChild(scrollDiv);
|
17
|
-
return scrollbarWidth;
|
18
|
-
};
|
19
|
-
})();
|
20
|
-
const useScrollLock = () => {
|
3
|
+
import { lockScroll, unlockScroll } from "../utilities/scroll/index.js";
|
4
|
+
const useScrollLock = (props) => {
|
5
|
+
const { containerRef } = props || {};
|
21
6
|
const [locked, setLocked] = React.useState(false);
|
22
|
-
const
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
}
|
34
|
-
setLocked(true);
|
35
|
-
}, [setLocked, isOverflowingRef, overflowStyleRef]);
|
36
|
-
const unlockScroll = React.useCallback(() => {
|
37
|
-
const targetEl = document.body;
|
38
|
-
targetEl.style.overflow = overflowStyleRef.current || "";
|
39
|
-
if (isOverflowingRef.current)
|
40
|
-
targetEl.style.paddingRight = "";
|
41
|
-
setLocked(false);
|
42
|
-
}, [setLocked, isOverflowingRef, overflowStyleRef]);
|
43
|
-
return { scrollLocked: locked, lockScroll, unlockScroll };
|
7
|
+
const handleLockScroll = React.useCallback(() => {
|
8
|
+
lockScroll({ containerEl: containerRef?.current, cb: () => setLocked(true) });
|
9
|
+
}, [containerRef]);
|
10
|
+
const handleUnlockScroll = React.useCallback(() => {
|
11
|
+
unlockScroll(() => setLocked(false));
|
12
|
+
}, []);
|
13
|
+
return React.useMemo(() => ({
|
14
|
+
scrollLocked: locked,
|
15
|
+
lockScroll: handleLockScroll,
|
16
|
+
unlockScroll: handleUnlockScroll,
|
17
|
+
}), [locked, handleLockScroll, handleUnlockScroll]);
|
44
18
|
};
|
45
19
|
export default useScrollLock;
|
package/dist/index.d.ts
CHANGED
@@ -41,6 +41,8 @@ export { default as FileUpload } from "./components/FileUpload";
|
|
41
41
|
export type { FileUploadProps } from "./components/FileUpload";
|
42
42
|
export { default as FormControl } from "./components/FormControl";
|
43
43
|
export type { FormControlProps } from "./components/FormControl";
|
44
|
+
export { default as Grid } from "./components/Grid";
|
45
|
+
export type { GridProps, GridItemProps } from "./components/Grid";
|
44
46
|
export { default as Hidden } from "./components/Hidden";
|
45
47
|
export type { HiddenProps } from "./components/Hidden";
|
46
48
|
export { default as HiddenVisually } from "./components/HiddenVisually";
|
package/dist/index.js
CHANGED
@@ -21,6 +21,7 @@ export { default as Divider } from "./components/Divider/index.js";
|
|
21
21
|
export { default as DropdownMenu } from "./components/DropdownMenu/index.js";
|
22
22
|
export { default as FileUpload } from "./components/FileUpload/index.js";
|
23
23
|
export { default as FormControl } from "./components/FormControl/index.js";
|
24
|
+
export { default as Grid } from "./components/Grid/index.js";
|
24
25
|
export { default as Hidden } from "./components/Hidden/index.js";
|
25
26
|
export { default as HiddenVisually } from "./components/HiddenVisually/index.js";
|
26
27
|
export { default as Hotkey } from "./components/Hotkey/index.js";
|
@@ -0,0 +1 @@
|
|
1
|
+
.--align-start{align-items:flex-start!important}.--align-end{align-items:flex-end!important}.--align-center{align-items:center!important}.--align-stretch{align-items:stretch!important}.--align-baseline{align-items:baseline!important}@media (--rs-viewport-m ){.--align-start--m{align-items:flex-start!important}.--align-end--m{align-items:flex-end!important}.--align-center--m{align-items:center!important}.--align-stretch--m{align-items:stretch!important}.--align-baseline--m{align-items:baseline!important}}@media (--rs-viewport-l ){.--align-start--l{align-items:flex-start!important}.--align-end--l{align-items:flex-end!important}.--align-center--l{align-items:center!important}.--align-stretch--l{align-items:stretch!important}.--align-baseline--l{align-items:baseline!important}}@media (--rs-viewport-xl ){.--align-start--xl{align-items:flex-start!important}.--align-end--xl{align-items:flex-end!important}.--align-center--xl{align-items:center!important}.--align-stretch--xl{align-items:stretch!important}.--align-baseline--xl{align-items:baseline!important}}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { responsiveClassNames } from "../../utilities/helpers.js";
|
2
|
+
import s from "./align.module.css";
|
3
|
+
const getAlignStyles = (value) => {
|
4
|
+
if (!value)
|
5
|
+
return null;
|
6
|
+
return {
|
7
|
+
classNames: responsiveClassNames(s, "--align", value),
|
8
|
+
};
|
9
|
+
};
|
10
|
+
export default getAlignStyles;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { responsiveClassNames } from "../../utilities/helpers.js";
|
2
|
+
import s from "./justify.module.css";
|
3
|
+
const getJustifyStyles = (value) => {
|
4
|
+
if (!value)
|
5
|
+
return null;
|
6
|
+
return {
|
7
|
+
classNames: responsiveClassNames(s, "--justify", value),
|
8
|
+
};
|
9
|
+
};
|
10
|
+
export default getJustifyStyles;
|
@@ -0,0 +1 @@
|
|
1
|
+
.--justify-start{justify-content:flex-start}.--justify-end{justify-content:flex-end}.--justify-center{justify-content:center}.--justify-space-between{justify-content:space-between}@media (--rs-viewport-m ){.--justify-start--m{justify-content:flex-start}.--justify-end--m{justify-content:flex-end}.--justify-center--m{justify-content:center}.--justify-space-between--m{justify-content:space-between}}@media (--rs-viewport-l ){.--justify-start--l{justify-content:flex-start}.--justify-end--l{justify-content:flex-end}.--justify-center--l{justify-content:center}.--justify-space-between--l{justify-content:space-between}}@media (--rs-viewport-xl ){.--justify-start--xl{justify-content:flex-start}.--justify-end--xl{justify-content:flex-end}.--justify-center--xl{justify-content:center}.--justify-space-between--xl{justify-content:space-between}}
|
package/dist/styles/types.d.ts
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
import React from "react";
|
2
2
|
import * as G from "../types/global";
|
3
3
|
export type TextAlign = "start" | "center" | "end";
|
4
|
+
export type Justify = "start" | "center" | "end" | "space-between";
|
5
|
+
export type Align = "start" | "center" | "end" | "stretch" | "baseline";
|
4
6
|
export type Radius = "small" | "medium" | "large" | "circular" | "none";
|
5
7
|
export type Position = "relative" | "absolute" | "fixed" | "sticky" | "static";
|
6
8
|
export type BorderColor = "neutral" | "neutral-faded" | "critical" | "critical-faded" | "warning" | "warning-faded" | "positive" | "positive-faded" | "primary" | "primary-faded" | "disabled" | "brand" | "transparent";
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import breakpoints from "../../../constants/breakpoints.js";
|
1
2
|
const theme = {
|
2
3
|
fontFamily: {
|
3
4
|
title: {
|
@@ -123,7 +124,7 @@ const theme = {
|
|
123
124
|
borderPositiveFaded: { hex: "#d0f3e2", hexDark: "#293b2f" },
|
124
125
|
foregroundPositive: { hex: "#0d7544", hexDark: "#18ab66" },
|
125
126
|
backgroundNeutral: { hex: "#dfe2ea", hexDark: "#494f60" },
|
126
|
-
backgroundNeutralFaded: { hex: "#
|
127
|
+
backgroundNeutralFaded: { hex: "#f3f3f5", hexDark: "#222835" },
|
127
128
|
borderNeutral: { hex: "#0000001f", hexDark: "#ffffff24" },
|
128
129
|
borderNeutralFaded: { hex: "#0000001a", hexDark: "#ffffff17" },
|
129
130
|
foregroundNeutral: { hex: "#14181f", hexDark: "#eff1f5" },
|
@@ -187,9 +188,9 @@ const theme = {
|
|
187
188
|
],
|
188
189
|
},
|
189
190
|
viewport: {
|
190
|
-
m: { minPx:
|
191
|
-
l: { minPx:
|
192
|
-
xl: { minPx:
|
191
|
+
m: { minPx: breakpoints.m },
|
192
|
+
l: { minPx: breakpoints.l },
|
193
|
+
xl: { minPx: breakpoints.xl },
|
193
194
|
},
|
194
195
|
};
|
195
196
|
export default theme;
|
@@ -4,7 +4,7 @@ const transformedToken = (name, token) => {
|
|
4
4
|
value.push(`(min-width: ${token.minPx}px)`);
|
5
5
|
if (token.maxPx)
|
6
6
|
value.push(`(max-width: ${token.maxPx}px)`);
|
7
|
-
|
7
|
+
const result = [
|
8
8
|
{
|
9
9
|
name,
|
10
10
|
tokenType: "viewport",
|
@@ -12,5 +12,14 @@ const transformedToken = (name, token) => {
|
|
12
12
|
value: value.join(" and "),
|
13
13
|
},
|
14
14
|
];
|
15
|
+
if (token.minPx) {
|
16
|
+
result.push({
|
17
|
+
name: `${name}-min`,
|
18
|
+
tokenType: "viewport",
|
19
|
+
type: "variable",
|
20
|
+
value: token.minPx.toString(),
|
21
|
+
});
|
22
|
+
}
|
23
|
+
return result;
|
15
24
|
};
|
16
25
|
export default transformedToken;
|