reshaped 3.5.4-canary.0 → 3.6.0-canary.1
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 +29 -46
- package/dist/bundle.css +1 -1
- package/dist/bundle.d.ts +37 -32
- package/dist/bundle.js +11 -11
- package/dist/components/Accordion/AccordionControlled.js +1 -1
- package/dist/components/Accordion/AccordionTrigger.js +1 -1
- package/dist/components/ActionBar/ActionBar.js +1 -1
- package/dist/components/Actionable/Actionable.js +1 -1
- package/dist/components/Avatar/Avatar.js +1 -1
- package/dist/components/Badge/Badge.js +1 -1
- package/dist/components/Badge/BadgeContainer.js +1 -1
- package/dist/components/Breadcrumbs/Breadcrumbs.js +1 -1
- package/dist/components/Button/Button.js +1 -1
- package/dist/components/Button/Button.types.d.ts +1 -1
- package/dist/components/Button/ButtonGroup.js +1 -1
- package/dist/components/Calendar/CalendarDate.js +1 -1
- package/dist/components/Card/Card.d.ts +1 -1
- package/dist/components/Card/Card.js +1 -1
- package/dist/components/Card/tests/Card.stories.d.ts +1 -1
- package/dist/components/Card/tests/Card.test.stories.d.ts +1 -1
- package/dist/components/Carousel/Carousel.js +4 -3
- package/dist/components/Carousel/CarouselControl.js +1 -1
- package/dist/components/Checkbox/Checkbox.js +1 -1
- package/dist/components/Container/Container.js +1 -1
- package/dist/components/Dismissible/Dismissible.js +1 -1
- package/dist/components/Divider/Divider.js +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js +2 -2
- package/dist/components/DropdownMenu/DropdownMenu.types.d.ts +1 -1
- package/dist/components/DropdownMenu/tests/DropdownMenu.stories.d.ts +1 -1
- package/dist/components/DropdownMenu/tests/DropdownMenu.test.stories.d.ts +1 -1
- package/dist/components/FileUpload/FileUpload.js +1 -1
- package/dist/components/Flyout/Flyout.constants.d.ts +6 -0
- package/dist/components/Flyout/Flyout.constants.js +19 -0
- package/dist/components/{_private/Flyout → Flyout}/Flyout.types.d.ts +3 -3
- package/dist/components/{_private/Flyout → Flyout}/FlyoutContent.js +28 -22
- package/dist/components/{_private/Flyout → Flyout}/FlyoutControlled.js +9 -9
- package/dist/components/{_private/Flyout → Flyout}/tests/Flyout.stories.d.ts +6 -4
- package/dist/components/{_private/Flyout → Flyout}/tests/Flyout.stories.js +128 -118
- package/dist/components/{_private/Flyout → Flyout}/useFlyout.d.ts +1 -1
- package/dist/components/Flyout/useFlyout.js +116 -0
- package/dist/components/Flyout/utilities/calculatePosition.d.ts +30 -0
- package/dist/components/Flyout/utilities/calculatePosition.js +129 -0
- package/dist/components/Flyout/utilities/flyout.d.ts +11 -0
- package/dist/components/Flyout/utilities/flyout.js +79 -0
- package/dist/components/Flyout/utilities/isFullyVisible.d.ts +10 -0
- package/dist/components/Flyout/utilities/isFullyVisible.js +24 -0
- package/dist/components/FormControl/FormControl.context.d.ts +0 -2
- package/dist/components/Grid/Grid.js +1 -1
- package/dist/components/Hidden/Hidden.js +1 -1
- package/dist/components/Hotkey/Hotkey.js +1 -1
- package/dist/components/Icon/Icon.js +1 -1
- package/dist/components/Image/Image.js +1 -1
- package/dist/components/Link/Link.d.ts +1 -1
- package/dist/components/Link/Link.js +1 -1
- package/dist/components/Loader/Loader.js +1 -1
- package/dist/components/MenuItem/MenuItem.js +1 -1
- package/dist/components/Modal/Modal.js +1 -1
- package/dist/components/NumberField/NumberFieldControlled.js +1 -1
- package/dist/components/Overlay/Overlay.js +1 -1
- package/dist/components/PinField/PinFieldControlled.js +1 -1
- package/dist/components/Popover/Popover.d.ts +1 -1
- package/dist/components/Popover/Popover.js +4 -4
- package/dist/components/Popover/Popover.module.css +1 -1
- package/dist/components/Popover/Popover.types.d.ts +3 -1
- package/dist/components/Popover/tests/Popover.stories.d.ts +48 -9
- package/dist/components/Popover/tests/Popover.stories.js +209 -85
- package/dist/components/Progress/Progress.js +1 -1
- package/dist/components/ProgressIndicator/ProgressIndicator.js +1 -1
- package/dist/components/Radio/Radio.js +1 -1
- package/dist/components/Reshaped/Reshaped.js +1 -1
- package/dist/components/Resizable/Resizable.js +1 -1
- package/dist/components/Scrim/Scrim.js +1 -1
- package/dist/components/ScrollArea/ScrollArea.js +6 -6
- package/dist/components/ScrollArea/ScrollArea.module.css +1 -1
- package/dist/components/Select/Select.js +1 -1
- package/dist/components/Skeleton/Skeleton.js +1 -1
- package/dist/components/Slider/Slider.types.d.ts +34 -7
- package/dist/components/Slider/SliderControlled.js +32 -20
- package/dist/components/Slider/SliderThumb.js +4 -4
- package/dist/components/Slider/SliderUncontrolled.js +3 -2
- package/dist/components/Slider/tests/Slider.stories.d.ts +38 -8
- package/dist/components/Slider/tests/Slider.stories.js +268 -54
- package/dist/components/Stepper/Stepper.js +1 -1
- package/dist/components/Switch/Switch.js +1 -1
- package/dist/components/Table/Table.js +6 -3
- package/dist/components/Table/Table.module.css +1 -1
- package/dist/components/Tabs/TabsContext.d.ts +2 -2
- package/dist/components/Tabs/TabsItem.js +1 -1
- package/dist/components/Tabs/TabsList.js +3 -34
- package/dist/components/Tabs/TabsPanel.js +1 -1
- package/dist/components/Text/Text.js +1 -1
- package/dist/components/TextArea/TextArea.js +1 -1
- package/dist/components/TextField/TextField.js +1 -1
- package/dist/components/Theme/Theme.js +1 -1
- package/dist/components/Timeline/Timeline.js +1 -1
- package/dist/components/Toast/ToastContainer.js +1 -1
- package/dist/components/Toast/ToastRegion.js +1 -1
- package/dist/components/Tooltip/Tooltip.js +1 -1
- package/dist/components/Tooltip/Tooltip.types.d.ts +1 -1
- package/dist/components/View/View.js +1 -1
- package/dist/components/_private/Aligner/Aligner.js +1 -1
- package/dist/components/_private/Expandable/Expandable.js +1 -1
- package/dist/components/_private/HiddenInput/HiddenInput.js +1 -1
- package/dist/config/tailwind.d.ts +1 -1
- package/dist/hooks/_private/useFadeSide.d.ts +5 -0
- package/dist/hooks/_private/useFadeSide.js +47 -0
- package/dist/hooks/useIsomorphicLayoutEffect.d.ts +1 -1
- package/dist/index.d.ts +37 -32
- package/dist/index.js +21 -17
- package/dist/styles/align/index.js +1 -1
- package/dist/styles/aspectRatio/index.js +1 -1
- package/dist/styles/bleed/index.js +1 -1
- package/dist/styles/border/index.js +1 -1
- package/dist/styles/height/index.js +1 -1
- package/dist/styles/inset/index.js +1 -1
- package/dist/styles/justify/index.js +1 -1
- package/dist/styles/maxHeight/index.js +1 -1
- package/dist/styles/maxWidth/index.js +1 -1
- package/dist/styles/minHeight/index.js +1 -1
- package/dist/styles/minWidth/index.js +1 -1
- package/dist/styles/padding/index.js +1 -1
- package/dist/styles/position/index.js +1 -1
- package/dist/styles/radius/index.js +1 -1
- package/dist/styles/textAlign/index.js +1 -1
- package/dist/styles/width/index.js +1 -1
- package/dist/utilities/dom/event.d.ts +7 -0
- package/dist/utilities/dom/event.js +11 -0
- package/dist/utilities/dom/find.d.ts +6 -9
- package/dist/utilities/dom/find.js +17 -15
- package/dist/utilities/dom/index.d.ts +2 -1
- package/dist/utilities/dom/index.js +2 -1
- package/dist/utilities/helpers.d.ts +1 -15
- package/dist/utilities/helpers.js +11 -133
- package/dist/utilities/props.d.ts +13 -0
- package/dist/utilities/props.js +83 -0
- package/dist/utilities/scroll/lock.js +4 -3
- package/package.json +24 -24
- package/CHANGELOG-old.md +0 -14
- package/dist/components/Popover/tests/Popover.test.stories.d.ts +0 -39
- package/dist/components/Popover/tests/Popover.test.stories.js +0 -167
- package/dist/components/Slider/tests/Slider.test.stories.d.ts +0 -38
- package/dist/components/Slider/tests/Slider.test.stories.js +0 -150
- package/dist/components/_private/Flyout/Flyout.constants.d.ts +0 -3
- package/dist/components/_private/Flyout/Flyout.constants.js +0 -3
- package/dist/components/_private/Flyout/useFlyout.js +0 -211
- package/dist/components/_private/Flyout/utilities/calculatePosition.d.ts +0 -19
- package/dist/components/_private/Flyout/utilities/calculatePosition.js +0 -102
- package/dist/components/_private/Flyout/utilities/isFullyVisible.d.ts +0 -8
- package/dist/components/_private/Flyout/utilities/isFullyVisible.js +0 -16
- /package/dist/components/{_private/Flyout → Flyout}/Flyout.context.d.ts +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/Flyout.context.js +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/Flyout.d.ts +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/Flyout.js +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/Flyout.module.css +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/Flyout.types.js +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/FlyoutContent.d.ts +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/FlyoutControlled.d.ts +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/FlyoutTrigger.d.ts +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/FlyoutTrigger.js +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/FlyoutUncontrolled.d.ts +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/FlyoutUncontrolled.js +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/index.d.ts +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/index.js +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/utilities/cooldown.d.ts +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/utilities/cooldown.js +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/utilities/getPositionFallbacks.d.ts +0 -0
- /package/dist/components/{_private/Flyout → Flyout}/utilities/getPositionFallbacks.js +0 -0
@@ -1,150 +0,0 @@
|
|
1
|
-
import { expect, fn, fireEvent } from "@storybook/test";
|
2
|
-
import Slider from "../index.js";
|
3
|
-
export default {
|
4
|
-
title: "Components/Slider/tests",
|
5
|
-
component: Slider,
|
6
|
-
parameters: {
|
7
|
-
iframe: {
|
8
|
-
url: "https://reshaped.so/docs/components/slider",
|
9
|
-
},
|
10
|
-
chromatic: { disableSnapshot: true },
|
11
|
-
},
|
12
|
-
};
|
13
|
-
export const defaultValue = {
|
14
|
-
name: "defaultValue, uncontrolled",
|
15
|
-
args: {
|
16
|
-
handleChange: fn(),
|
17
|
-
handleChangeCommit: fn(),
|
18
|
-
},
|
19
|
-
render: (args) => (<Slider name="test-name" defaultValue={50} onChange={args.handleChange} onChangeCommit={args.handleChangeCommit}/>),
|
20
|
-
play: async ({ canvas, args }) => {
|
21
|
-
const input = canvas.getByRole("slider");
|
22
|
-
expect(input).toHaveValue("50");
|
23
|
-
fireEvent.change(input, { target: { value: 51 } });
|
24
|
-
expect(args.handleChange).toHaveBeenCalledTimes(1);
|
25
|
-
expect(args.handleChange).toHaveBeenCalledWith({ value: 51, name: "test-name" });
|
26
|
-
expect(input).toHaveValue("51");
|
27
|
-
},
|
28
|
-
};
|
29
|
-
export const value = {
|
30
|
-
name: "value, controlled",
|
31
|
-
args: {
|
32
|
-
handleChange: fn(),
|
33
|
-
handleChangeCommit: fn(),
|
34
|
-
},
|
35
|
-
render: (args) => (<Slider name="test-name" value={50} onChange={args.handleChange} onChangeCommit={args.handleChangeCommit}/>),
|
36
|
-
play: async ({ canvas, args }) => {
|
37
|
-
const input = canvas.getByRole("slider");
|
38
|
-
expect(input).toHaveValue("50");
|
39
|
-
fireEvent.change(input, { target: { value: 51 } });
|
40
|
-
expect(args.handleChange).toHaveBeenCalledTimes(1);
|
41
|
-
expect(args.handleChange).toHaveBeenCalledWith({ value: 51, name: "test-name" });
|
42
|
-
expect(input).toHaveValue("50");
|
43
|
-
},
|
44
|
-
};
|
45
|
-
export const rangeDefaultValue = {
|
46
|
-
name: "range, defaultValue, uncontrolled",
|
47
|
-
args: {
|
48
|
-
handleChange: fn(),
|
49
|
-
handleChangeCommit: fn(),
|
50
|
-
},
|
51
|
-
render: (args) => (<Slider range name="test-name" defaultMinValue={50} defaultMaxValue={70} onChange={args.handleChange} onChangeCommit={args.handleChangeCommit}/>),
|
52
|
-
play: async ({ canvas, args }) => {
|
53
|
-
const [minInput, maxInput] = canvas.getAllByRole("slider");
|
54
|
-
expect(minInput).toHaveValue("50");
|
55
|
-
expect(maxInput).toHaveValue("70");
|
56
|
-
fireEvent.change(minInput, { target: { value: 51 } });
|
57
|
-
expect(args.handleChange).toHaveBeenCalledTimes(1);
|
58
|
-
expect(args.handleChange).toHaveBeenCalledWith({
|
59
|
-
minValue: 51,
|
60
|
-
maxValue: 70,
|
61
|
-
name: "test-name",
|
62
|
-
});
|
63
|
-
expect(minInput).toHaveValue("51");
|
64
|
-
expect(maxInput).toHaveValue("70");
|
65
|
-
},
|
66
|
-
};
|
67
|
-
export const rangeValue = {
|
68
|
-
name: "range, value, controlled",
|
69
|
-
args: {
|
70
|
-
handleChange: fn(),
|
71
|
-
handleChangeCommit: fn(),
|
72
|
-
},
|
73
|
-
render: (args) => (<Slider range name="test-name" minValue={50} maxValue={70} onChange={args.handleChange} onChangeCommit={args.handleChangeCommit}/>),
|
74
|
-
play: async ({ canvas, args }) => {
|
75
|
-
const [minInput, maxInput] = canvas.getAllByRole("slider");
|
76
|
-
expect(minInput).toHaveValue("50");
|
77
|
-
expect(maxInput).toHaveValue("70");
|
78
|
-
fireEvent.change(minInput, { target: { value: 51 } });
|
79
|
-
expect(args.handleChange).toHaveBeenCalledTimes(1);
|
80
|
-
expect(args.handleChange).toHaveBeenCalledWith({
|
81
|
-
minValue: 51,
|
82
|
-
maxValue: 70,
|
83
|
-
name: "test-name",
|
84
|
-
});
|
85
|
-
expect(minInput).toHaveValue("50");
|
86
|
-
expect(maxInput).toHaveValue("70");
|
87
|
-
},
|
88
|
-
};
|
89
|
-
export const minMax = {
|
90
|
-
name: "min, max",
|
91
|
-
render: () => <Slider name="nmae" range min={50} max={70}/>,
|
92
|
-
play: async ({ canvas }) => {
|
93
|
-
const [minInputEl, maxInputEl] = canvas.getAllByRole("slider");
|
94
|
-
expect(minInputEl).toHaveAttribute("min", "50");
|
95
|
-
expect(minInputEl).toHaveAttribute("max", "70");
|
96
|
-
expect(maxInputEl).toHaveAttribute("min", "50");
|
97
|
-
expect(maxInputEl).toHaveAttribute("max", "70");
|
98
|
-
},
|
99
|
-
};
|
100
|
-
export const step = {
|
101
|
-
name: "step",
|
102
|
-
render: () => <Slider name="name" defaultValue={11} step={5}/>,
|
103
|
-
play: async ({ canvas }) => {
|
104
|
-
const inputEl = canvas.getByRole("slider");
|
105
|
-
expect(inputEl).toHaveValue("10");
|
106
|
-
},
|
107
|
-
};
|
108
|
-
export const stepFloat = {
|
109
|
-
name: "step, float",
|
110
|
-
render: () => <Slider name="name" defaultValue={20.24} step={0.1}/>,
|
111
|
-
play: async ({ canvas }) => {
|
112
|
-
const inputEl = canvas.getByRole("slider");
|
113
|
-
expect(inputEl).toHaveValue("20.2");
|
114
|
-
},
|
115
|
-
};
|
116
|
-
export const renderValue = {
|
117
|
-
name: "renderValue",
|
118
|
-
render: () => <Slider name="name" defaultValue={50} renderValue={(args) => `$${args.value}`}/>,
|
119
|
-
play: async ({ canvas }) => {
|
120
|
-
const tooltipEl = canvas.getByText(`$50`);
|
121
|
-
expect(tooltipEl).toBeInTheDocument();
|
122
|
-
},
|
123
|
-
};
|
124
|
-
export const withoutTooltipValue = {
|
125
|
-
name: "renderValue=false",
|
126
|
-
render: () => <Slider name="name" defaultValue={50} renderValue={false}/>,
|
127
|
-
play: async ({ canvas }) => {
|
128
|
-
const tooltipEl = canvas.queryByText(`$50`);
|
129
|
-
expect(tooltipEl).not.toBeInTheDocument();
|
130
|
-
},
|
131
|
-
};
|
132
|
-
export const disabled = {
|
133
|
-
name: "disabled",
|
134
|
-
render: () => <Slider name="name" defaultValue={50} disabled/>,
|
135
|
-
play: async ({ canvas }) => {
|
136
|
-
const inputEl = canvas.getByRole("slider");
|
137
|
-
expect(inputEl).toBeDisabled();
|
138
|
-
},
|
139
|
-
};
|
140
|
-
export const className = {
|
141
|
-
name: "className, attributes",
|
142
|
-
render: () => (<div data-testid="root">
|
143
|
-
<Slider name="name" className="test-classname" attributes={{ id: "test-id" }}/>
|
144
|
-
</div>),
|
145
|
-
play: async ({ canvas }) => {
|
146
|
-
const root = canvas.getByTestId("root").firstChild;
|
147
|
-
expect(root).toHaveClass("test-classname");
|
148
|
-
expect(root).toHaveAttribute("id", "test-id");
|
149
|
-
},
|
150
|
-
};
|
@@ -1,211 +0,0 @@
|
|
1
|
-
import React from "react";
|
2
|
-
import useRTL from "../../../hooks/useRTL.js";
|
3
|
-
import { findClosestRenderContainer, getShadowRoot, getRectFromCoordinates } from "../../../utilities/dom/index.js";
|
4
|
-
import calculatePosition from "./utilities/calculatePosition.js";
|
5
|
-
import getPositionFallbacks from "./utilities/getPositionFallbacks.js";
|
6
|
-
import isFullyVisible from "./utilities/isFullyVisible.js";
|
7
|
-
/**
|
8
|
-
* Order of keys here is responsible for the order of styles applied
|
9
|
-
*/
|
10
|
-
const defaultStyles = {
|
11
|
-
left: 0,
|
12
|
-
top: 0,
|
13
|
-
width: "auto",
|
14
|
-
height: "auto",
|
15
|
-
// z-index doesn't accept strings
|
16
|
-
zIndex: "var(--rs-z-index-flyout)",
|
17
|
-
};
|
18
|
-
const resetStyles = {
|
19
|
-
left: 0,
|
20
|
-
top: 0,
|
21
|
-
position: "absolute",
|
22
|
-
visibility: "hidden",
|
23
|
-
animation: "none",
|
24
|
-
transition: "none",
|
25
|
-
zIndex: "var(--rs-z-index-tooltip)",
|
26
|
-
};
|
27
|
-
/**
|
28
|
-
* Set position of the target element to fit on the screen
|
29
|
-
*/
|
30
|
-
const flyout = (args) => {
|
31
|
-
const { triggerEl, flyoutEl, triggerBounds: passedTriggerBounds, contentShift = 0, contentGap = 0, ...options } = args;
|
32
|
-
const { position, fallbackPositions, width, container, lastUsedFallback, onFallback } = options;
|
33
|
-
const targetClone = flyoutEl.cloneNode(true);
|
34
|
-
const baseUnit = getComputedStyle(flyoutEl).getPropertyValue("--rs-unit-x1");
|
35
|
-
const unitModifier = baseUnit ? parseInt(baseUnit) : 0;
|
36
|
-
const internalTriggerBounds = triggerEl?.getBoundingClientRect();
|
37
|
-
const triggerBounds = passedTriggerBounds || internalTriggerBounds;
|
38
|
-
if (!triggerBounds)
|
39
|
-
return;
|
40
|
-
const resolvedTriggerBounds = getRectFromCoordinates(triggerBounds);
|
41
|
-
// Reset all styles applied on the previous hook execution
|
42
|
-
targetClone.style.cssText = "";
|
43
|
-
Object.keys(resetStyles).forEach((key) => {
|
44
|
-
const value = resetStyles[key];
|
45
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
46
|
-
// @ts-ignore
|
47
|
-
if (value)
|
48
|
-
targetClone.style[key] = value.toString();
|
49
|
-
});
|
50
|
-
if (width) {
|
51
|
-
if (width === "trigger") {
|
52
|
-
targetClone.style.width = `${resolvedTriggerBounds.width}px`;
|
53
|
-
}
|
54
|
-
else if (width !== "full") {
|
55
|
-
targetClone.style.width = width;
|
56
|
-
}
|
57
|
-
}
|
58
|
-
const shadowRoot = triggerEl && getShadowRoot(triggerEl);
|
59
|
-
// Insert inside shadow root if possible to make sure styles are applied correctly
|
60
|
-
(shadowRoot || document.body).appendChild(targetClone);
|
61
|
-
const flyoutBounds = targetClone.getBoundingClientRect();
|
62
|
-
const closestRenderContainer = !container && triggerEl ? findClosestRenderContainer({ el: triggerEl }) : undefined;
|
63
|
-
const containerParent = container ||
|
64
|
-
// Only render inside non-scrollable container to make sure it doesn't get clipped by overflow auto
|
65
|
-
// We render those cases in the document root and then sync the position on scroll instead
|
66
|
-
(!closestRenderContainer?.scrollable ? closestRenderContainer?.el : undefined) ||
|
67
|
-
document.body;
|
68
|
-
const containerBounds = containerParent.getBoundingClientRect();
|
69
|
-
const scopeOffset = {
|
70
|
-
top: containerBounds.top + document.documentElement.scrollTop - containerParent.scrollTop,
|
71
|
-
left: containerBounds.left + document.documentElement.scrollLeft - containerParent.scrollLeft,
|
72
|
-
};
|
73
|
-
let calculated = null;
|
74
|
-
const testOrder = getPositionFallbacks(position, fallbackPositions);
|
75
|
-
testOrder.some((currentPosition) => {
|
76
|
-
const tested = calculatePosition({
|
77
|
-
...options,
|
78
|
-
triggerBounds: resolvedTriggerBounds,
|
79
|
-
flyoutBounds,
|
80
|
-
scopeOffset,
|
81
|
-
position: currentPosition,
|
82
|
-
contentGap: contentGap * unitModifier,
|
83
|
-
contentShift: contentShift * unitModifier,
|
84
|
-
});
|
85
|
-
const visible = isFullyVisible({ ...tested, container });
|
86
|
-
const validPosition = visible || fallbackPositions?.length === 0;
|
87
|
-
// Saving first try in case non of the options work
|
88
|
-
if (validPosition || lastUsedFallback === currentPosition) {
|
89
|
-
calculated = tested;
|
90
|
-
onFallback(currentPosition);
|
91
|
-
}
|
92
|
-
return validPosition;
|
93
|
-
});
|
94
|
-
if (!calculated) {
|
95
|
-
throw new Error(`[Reshaped] Can't calculate styles for the ${position} position`);
|
96
|
-
}
|
97
|
-
targetClone.parentNode?.removeChild(targetClone);
|
98
|
-
return calculated;
|
99
|
-
};
|
100
|
-
const flyoutReducer = (state, action) => {
|
101
|
-
switch (action.type) {
|
102
|
-
case "render":
|
103
|
-
if (state.status !== "idle")
|
104
|
-
return state;
|
105
|
-
// Disable events before it's positioned to avoid mouseleave getting triggered
|
106
|
-
return { ...state, status: "rendered", styles: { pointerEvents: "none", ...resetStyles } };
|
107
|
-
case "position":
|
108
|
-
if (!action.payload.sync && state.status !== "rendered")
|
109
|
-
return state;
|
110
|
-
if (action.payload.sync && state.status !== "visible")
|
111
|
-
return state;
|
112
|
-
return {
|
113
|
-
...state,
|
114
|
-
status: action.payload.sync ? "visible" : "positioned",
|
115
|
-
position: action.payload.position,
|
116
|
-
styles: { ...defaultStyles, ...action.payload.styles },
|
117
|
-
};
|
118
|
-
case "show":
|
119
|
-
if (state.status !== "positioned")
|
120
|
-
return state;
|
121
|
-
return { ...state, status: "visible" };
|
122
|
-
case "hide":
|
123
|
-
if (state.status !== "visible")
|
124
|
-
return state;
|
125
|
-
return { ...state, status: "hidden" };
|
126
|
-
case "remove":
|
127
|
-
if (state.status !== "hidden" && state.status !== "visible")
|
128
|
-
return state;
|
129
|
-
return { ...state, status: "idle", styles: resetStyles };
|
130
|
-
default:
|
131
|
-
throw new Error("[Reshaped] Invalid flyout reducer type");
|
132
|
-
}
|
133
|
-
};
|
134
|
-
const useFlyout = (args) => {
|
135
|
-
const { triggerElRef, flyoutElRef, triggerBounds, contentGap, contentShift, ...options } = args;
|
136
|
-
const { position: defaultPosition = "bottom", fallbackPositions, width, container } = options;
|
137
|
-
const lastUsedFallbackRef = React.useRef(defaultPosition);
|
138
|
-
// Memo the array internally to avoid new arrays triggering useCallback
|
139
|
-
const cachedFallbackPositions = React.useMemo(() => fallbackPositions,
|
140
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
141
|
-
[fallbackPositions?.join(" ")]);
|
142
|
-
const [isRTL] = useRTL();
|
143
|
-
const [state, dispatch] = React.useReducer(flyoutReducer, {
|
144
|
-
position: defaultPosition,
|
145
|
-
styles: defaultStyles,
|
146
|
-
status: "idle",
|
147
|
-
});
|
148
|
-
const render = React.useCallback(() => {
|
149
|
-
dispatch({ type: "render" });
|
150
|
-
}, []);
|
151
|
-
const show = React.useCallback(() => {
|
152
|
-
dispatch({ type: "show" });
|
153
|
-
}, []);
|
154
|
-
const hide = React.useCallback(() => {
|
155
|
-
dispatch({ type: "hide" });
|
156
|
-
}, []);
|
157
|
-
const remove = React.useCallback(() => {
|
158
|
-
dispatch({ type: "remove" });
|
159
|
-
}, []);
|
160
|
-
const handleFallback = React.useCallback((position) => {
|
161
|
-
lastUsedFallbackRef.current = position;
|
162
|
-
}, []);
|
163
|
-
const updatePosition = React.useCallback((options) => {
|
164
|
-
if (!flyoutElRef.current)
|
165
|
-
return;
|
166
|
-
const nextFlyoutData = flyout({
|
167
|
-
triggerEl: triggerElRef.current,
|
168
|
-
flyoutEl: flyoutElRef.current,
|
169
|
-
triggerBounds,
|
170
|
-
width,
|
171
|
-
position: defaultPosition,
|
172
|
-
fallbackPositions: cachedFallbackPositions,
|
173
|
-
lastUsedFallback: lastUsedFallbackRef.current,
|
174
|
-
onFallback: handleFallback,
|
175
|
-
rtl: isRTL,
|
176
|
-
container,
|
177
|
-
contentGap,
|
178
|
-
contentShift,
|
179
|
-
});
|
180
|
-
if (nextFlyoutData) {
|
181
|
-
dispatch({ type: "position", payload: { ...nextFlyoutData, sync: options?.sync } });
|
182
|
-
}
|
183
|
-
}, [
|
184
|
-
container,
|
185
|
-
defaultPosition,
|
186
|
-
cachedFallbackPositions,
|
187
|
-
isRTL,
|
188
|
-
flyoutElRef,
|
189
|
-
triggerElRef,
|
190
|
-
triggerBounds,
|
191
|
-
width,
|
192
|
-
contentGap,
|
193
|
-
contentShift,
|
194
|
-
handleFallback,
|
195
|
-
]);
|
196
|
-
React.useEffect(() => {
|
197
|
-
if (state.status === "rendered")
|
198
|
-
updatePosition();
|
199
|
-
}, [state.status, updatePosition]);
|
200
|
-
return React.useMemo(() => ({
|
201
|
-
position: state.position,
|
202
|
-
styles: state.styles,
|
203
|
-
status: state.status,
|
204
|
-
updatePosition,
|
205
|
-
render,
|
206
|
-
hide,
|
207
|
-
remove,
|
208
|
-
show,
|
209
|
-
}), [render, updatePosition, hide, remove, show, state.position, state.styles, state.status]);
|
210
|
-
};
|
211
|
-
export default useFlyout;
|
@@ -1,19 +0,0 @@
|
|
1
|
-
import type * as T from "../Flyout.types";
|
2
|
-
/**
|
3
|
-
* Calculate styles for the current position
|
4
|
-
*/
|
5
|
-
declare const calculatePosition: (args: T.Options & {
|
6
|
-
triggerBounds: DOMRect;
|
7
|
-
flyoutBounds: DOMRect;
|
8
|
-
scopeOffset: Record<"left" | "top", number>;
|
9
|
-
}) => {
|
10
|
-
styles: {
|
11
|
-
left: number;
|
12
|
-
top: number;
|
13
|
-
width: number;
|
14
|
-
height: number;
|
15
|
-
};
|
16
|
-
position: T.Position;
|
17
|
-
scopeOffset: Record<"left" | "top", number>;
|
18
|
-
};
|
19
|
-
export default calculatePosition;
|
@@ -1,102 +0,0 @@
|
|
1
|
-
const SCREEN_OFFSET = 16;
|
2
|
-
const getRTLPosition = (position) => {
|
3
|
-
if (position.includes("start"))
|
4
|
-
return position.replace("start", "end");
|
5
|
-
if (position.includes("end"))
|
6
|
-
return position.replace("end", "start");
|
7
|
-
return position;
|
8
|
-
};
|
9
|
-
/**
|
10
|
-
* Get a position value which centers 2 elements vertically or horizontally
|
11
|
-
*/
|
12
|
-
const centerBySize = (originSize, targetSize) => {
|
13
|
-
return Math.floor(originSize / 2 - targetSize / 2);
|
14
|
-
};
|
15
|
-
/**
|
16
|
-
* Calculate styles for the current position
|
17
|
-
*/
|
18
|
-
const calculatePosition = (args) => {
|
19
|
-
const { triggerBounds, flyoutBounds, scopeOffset, position: passedPosition, rtl, width, contentGap = 0, contentShift = 0, } = args;
|
20
|
-
const isFullWidth = width === "full" || width === "100%";
|
21
|
-
let left = 0;
|
22
|
-
let top = 0;
|
23
|
-
let position = passedPosition;
|
24
|
-
if (rtl)
|
25
|
-
position = getRTLPosition(position);
|
26
|
-
if (isFullWidth || width === "trigger") {
|
27
|
-
position = position.includes("top") ? "top" : "bottom";
|
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);
|
33
|
-
switch (position) {
|
34
|
-
case "bottom":
|
35
|
-
case "top":
|
36
|
-
left = centerBySize(triggerBounds.width, flyoutWidth) + triggerBounds.left + contentShift;
|
37
|
-
break;
|
38
|
-
case "start":
|
39
|
-
case "start-top":
|
40
|
-
case "start-bottom":
|
41
|
-
left = triggerBounds.left - flyoutWidth;
|
42
|
-
break;
|
43
|
-
case "end":
|
44
|
-
case "end-top":
|
45
|
-
case "end-bottom":
|
46
|
-
left = triggerBounds.right;
|
47
|
-
break;
|
48
|
-
case "top-start":
|
49
|
-
case "bottom-start":
|
50
|
-
left = triggerBounds.left + contentShift + contentShift;
|
51
|
-
break;
|
52
|
-
case "top-end":
|
53
|
-
case "bottom-end":
|
54
|
-
left = triggerBounds.right - flyoutWidth + contentShift;
|
55
|
-
break;
|
56
|
-
default:
|
57
|
-
break;
|
58
|
-
}
|
59
|
-
switch (position) {
|
60
|
-
case "top":
|
61
|
-
case "top-start":
|
62
|
-
case "top-end":
|
63
|
-
top = triggerBounds.top - flyoutHeight;
|
64
|
-
break;
|
65
|
-
case "bottom":
|
66
|
-
case "bottom-start":
|
67
|
-
case "bottom-end":
|
68
|
-
top = triggerBounds.bottom;
|
69
|
-
break;
|
70
|
-
case "start":
|
71
|
-
case "end":
|
72
|
-
top = centerBySize(triggerBounds.height, flyoutHeight) + triggerBounds.top + contentShift;
|
73
|
-
break;
|
74
|
-
case "start-top":
|
75
|
-
case "end-top":
|
76
|
-
top = triggerBounds.top + contentShift;
|
77
|
-
break;
|
78
|
-
case "start-bottom":
|
79
|
-
case "end-bottom":
|
80
|
-
top = triggerBounds.bottom - flyoutHeight + contentShift;
|
81
|
-
break;
|
82
|
-
default:
|
83
|
-
break;
|
84
|
-
}
|
85
|
-
if (top === undefined || left === undefined) {
|
86
|
-
throw Error(`[Reshaped, flyout]: ${position} position is not valid`);
|
87
|
-
}
|
88
|
-
top = Math.round(top + (window.scrollY || 0) - scopeOffset.top);
|
89
|
-
left = Math.round(left + (window.scrollX || 0) - scopeOffset.left);
|
90
|
-
let widthStyle = Math.ceil(flyoutWidth);
|
91
|
-
const height = Math.ceil(flyoutHeight);
|
92
|
-
if (isFullWidth) {
|
93
|
-
left = SCREEN_OFFSET;
|
94
|
-
widthStyle = window.innerWidth - SCREEN_OFFSET * 2;
|
95
|
-
}
|
96
|
-
else if (width === "trigger") {
|
97
|
-
widthStyle = triggerBounds.width;
|
98
|
-
}
|
99
|
-
const styles = { left, top, width: widthStyle, height };
|
100
|
-
return { styles, position, scopeOffset };
|
101
|
-
};
|
102
|
-
export default calculatePosition;
|
@@ -1,8 +0,0 @@
|
|
1
|
-
import calculatePosition from "./calculatePosition";
|
2
|
-
/**
|
3
|
-
* Check if element visually fits on the screen
|
4
|
-
*/
|
5
|
-
declare const isFullyVisible: (args: ReturnType<typeof calculatePosition> & {
|
6
|
-
container?: HTMLElement | null;
|
7
|
-
}) => boolean;
|
8
|
-
export default isFullyVisible;
|
@@ -1,16 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Check if element visually fits on the screen
|
3
|
-
*/
|
4
|
-
const isFullyVisible = (args) => {
|
5
|
-
const { styles, scopeOffset, container } = args;
|
6
|
-
const htmlEl = container || document.documentElement;
|
7
|
-
const pageLeft = htmlEl.scrollLeft;
|
8
|
-
const pageRight = pageLeft + htmlEl.clientWidth;
|
9
|
-
const pageTop = htmlEl.scrollTop;
|
10
|
-
const pageBottom = pageTop + htmlEl.clientHeight;
|
11
|
-
return (styles.left + scopeOffset.left >= pageLeft &&
|
12
|
-
styles.left + styles.width + scopeOffset.left <= pageRight &&
|
13
|
-
styles.top + scopeOffset.top >= pageTop &&
|
14
|
-
styles.top + styles.height + scopeOffset.top <= pageBottom);
|
15
|
-
};
|
16
|
-
export default isFullyVisible;
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|