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.
Files changed (167) hide show
  1. package/CHANGELOG.md +29 -46
  2. package/dist/bundle.css +1 -1
  3. package/dist/bundle.d.ts +37 -32
  4. package/dist/bundle.js +11 -11
  5. package/dist/components/Accordion/AccordionControlled.js +1 -1
  6. package/dist/components/Accordion/AccordionTrigger.js +1 -1
  7. package/dist/components/ActionBar/ActionBar.js +1 -1
  8. package/dist/components/Actionable/Actionable.js +1 -1
  9. package/dist/components/Avatar/Avatar.js +1 -1
  10. package/dist/components/Badge/Badge.js +1 -1
  11. package/dist/components/Badge/BadgeContainer.js +1 -1
  12. package/dist/components/Breadcrumbs/Breadcrumbs.js +1 -1
  13. package/dist/components/Button/Button.js +1 -1
  14. package/dist/components/Button/Button.types.d.ts +1 -1
  15. package/dist/components/Button/ButtonGroup.js +1 -1
  16. package/dist/components/Calendar/CalendarDate.js +1 -1
  17. package/dist/components/Card/Card.d.ts +1 -1
  18. package/dist/components/Card/Card.js +1 -1
  19. package/dist/components/Card/tests/Card.stories.d.ts +1 -1
  20. package/dist/components/Card/tests/Card.test.stories.d.ts +1 -1
  21. package/dist/components/Carousel/Carousel.js +4 -3
  22. package/dist/components/Carousel/CarouselControl.js +1 -1
  23. package/dist/components/Checkbox/Checkbox.js +1 -1
  24. package/dist/components/Container/Container.js +1 -1
  25. package/dist/components/Dismissible/Dismissible.js +1 -1
  26. package/dist/components/Divider/Divider.js +1 -1
  27. package/dist/components/DropdownMenu/DropdownMenu.js +2 -2
  28. package/dist/components/DropdownMenu/DropdownMenu.types.d.ts +1 -1
  29. package/dist/components/DropdownMenu/tests/DropdownMenu.stories.d.ts +1 -1
  30. package/dist/components/DropdownMenu/tests/DropdownMenu.test.stories.d.ts +1 -1
  31. package/dist/components/FileUpload/FileUpload.js +1 -1
  32. package/dist/components/Flyout/Flyout.constants.d.ts +6 -0
  33. package/dist/components/Flyout/Flyout.constants.js +19 -0
  34. package/dist/components/{_private/Flyout → Flyout}/Flyout.types.d.ts +3 -3
  35. package/dist/components/{_private/Flyout → Flyout}/FlyoutContent.js +28 -22
  36. package/dist/components/{_private/Flyout → Flyout}/FlyoutControlled.js +9 -9
  37. package/dist/components/{_private/Flyout → Flyout}/tests/Flyout.stories.d.ts +6 -4
  38. package/dist/components/{_private/Flyout → Flyout}/tests/Flyout.stories.js +128 -118
  39. package/dist/components/{_private/Flyout → Flyout}/useFlyout.d.ts +1 -1
  40. package/dist/components/Flyout/useFlyout.js +116 -0
  41. package/dist/components/Flyout/utilities/calculatePosition.d.ts +30 -0
  42. package/dist/components/Flyout/utilities/calculatePosition.js +129 -0
  43. package/dist/components/Flyout/utilities/flyout.d.ts +11 -0
  44. package/dist/components/Flyout/utilities/flyout.js +79 -0
  45. package/dist/components/Flyout/utilities/isFullyVisible.d.ts +10 -0
  46. package/dist/components/Flyout/utilities/isFullyVisible.js +24 -0
  47. package/dist/components/FormControl/FormControl.context.d.ts +0 -2
  48. package/dist/components/Grid/Grid.js +1 -1
  49. package/dist/components/Hidden/Hidden.js +1 -1
  50. package/dist/components/Hotkey/Hotkey.js +1 -1
  51. package/dist/components/Icon/Icon.js +1 -1
  52. package/dist/components/Image/Image.js +1 -1
  53. package/dist/components/Link/Link.d.ts +1 -1
  54. package/dist/components/Link/Link.js +1 -1
  55. package/dist/components/Loader/Loader.js +1 -1
  56. package/dist/components/MenuItem/MenuItem.js +1 -1
  57. package/dist/components/Modal/Modal.js +1 -1
  58. package/dist/components/NumberField/NumberFieldControlled.js +1 -1
  59. package/dist/components/Overlay/Overlay.js +1 -1
  60. package/dist/components/PinField/PinFieldControlled.js +1 -1
  61. package/dist/components/Popover/Popover.d.ts +1 -1
  62. package/dist/components/Popover/Popover.js +4 -4
  63. package/dist/components/Popover/Popover.module.css +1 -1
  64. package/dist/components/Popover/Popover.types.d.ts +3 -1
  65. package/dist/components/Popover/tests/Popover.stories.d.ts +48 -9
  66. package/dist/components/Popover/tests/Popover.stories.js +209 -85
  67. package/dist/components/Progress/Progress.js +1 -1
  68. package/dist/components/ProgressIndicator/ProgressIndicator.js +1 -1
  69. package/dist/components/Radio/Radio.js +1 -1
  70. package/dist/components/Reshaped/Reshaped.js +1 -1
  71. package/dist/components/Resizable/Resizable.js +1 -1
  72. package/dist/components/Scrim/Scrim.js +1 -1
  73. package/dist/components/ScrollArea/ScrollArea.js +6 -6
  74. package/dist/components/ScrollArea/ScrollArea.module.css +1 -1
  75. package/dist/components/Select/Select.js +1 -1
  76. package/dist/components/Skeleton/Skeleton.js +1 -1
  77. package/dist/components/Slider/Slider.types.d.ts +34 -7
  78. package/dist/components/Slider/SliderControlled.js +32 -20
  79. package/dist/components/Slider/SliderThumb.js +4 -4
  80. package/dist/components/Slider/SliderUncontrolled.js +3 -2
  81. package/dist/components/Slider/tests/Slider.stories.d.ts +38 -8
  82. package/dist/components/Slider/tests/Slider.stories.js +268 -54
  83. package/dist/components/Stepper/Stepper.js +1 -1
  84. package/dist/components/Switch/Switch.js +1 -1
  85. package/dist/components/Table/Table.js +6 -3
  86. package/dist/components/Table/Table.module.css +1 -1
  87. package/dist/components/Tabs/TabsContext.d.ts +2 -2
  88. package/dist/components/Tabs/TabsItem.js +1 -1
  89. package/dist/components/Tabs/TabsList.js +3 -34
  90. package/dist/components/Tabs/TabsPanel.js +1 -1
  91. package/dist/components/Text/Text.js +1 -1
  92. package/dist/components/TextArea/TextArea.js +1 -1
  93. package/dist/components/TextField/TextField.js +1 -1
  94. package/dist/components/Theme/Theme.js +1 -1
  95. package/dist/components/Timeline/Timeline.js +1 -1
  96. package/dist/components/Toast/ToastContainer.js +1 -1
  97. package/dist/components/Toast/ToastRegion.js +1 -1
  98. package/dist/components/Tooltip/Tooltip.js +1 -1
  99. package/dist/components/Tooltip/Tooltip.types.d.ts +1 -1
  100. package/dist/components/View/View.js +1 -1
  101. package/dist/components/_private/Aligner/Aligner.js +1 -1
  102. package/dist/components/_private/Expandable/Expandable.js +1 -1
  103. package/dist/components/_private/HiddenInput/HiddenInput.js +1 -1
  104. package/dist/config/tailwind.d.ts +1 -1
  105. package/dist/hooks/_private/useFadeSide.d.ts +5 -0
  106. package/dist/hooks/_private/useFadeSide.js +47 -0
  107. package/dist/hooks/useIsomorphicLayoutEffect.d.ts +1 -1
  108. package/dist/index.d.ts +37 -32
  109. package/dist/index.js +21 -17
  110. package/dist/styles/align/index.js +1 -1
  111. package/dist/styles/aspectRatio/index.js +1 -1
  112. package/dist/styles/bleed/index.js +1 -1
  113. package/dist/styles/border/index.js +1 -1
  114. package/dist/styles/height/index.js +1 -1
  115. package/dist/styles/inset/index.js +1 -1
  116. package/dist/styles/justify/index.js +1 -1
  117. package/dist/styles/maxHeight/index.js +1 -1
  118. package/dist/styles/maxWidth/index.js +1 -1
  119. package/dist/styles/minHeight/index.js +1 -1
  120. package/dist/styles/minWidth/index.js +1 -1
  121. package/dist/styles/padding/index.js +1 -1
  122. package/dist/styles/position/index.js +1 -1
  123. package/dist/styles/radius/index.js +1 -1
  124. package/dist/styles/textAlign/index.js +1 -1
  125. package/dist/styles/width/index.js +1 -1
  126. package/dist/utilities/dom/event.d.ts +7 -0
  127. package/dist/utilities/dom/event.js +11 -0
  128. package/dist/utilities/dom/find.d.ts +6 -9
  129. package/dist/utilities/dom/find.js +17 -15
  130. package/dist/utilities/dom/index.d.ts +2 -1
  131. package/dist/utilities/dom/index.js +2 -1
  132. package/dist/utilities/helpers.d.ts +1 -15
  133. package/dist/utilities/helpers.js +11 -133
  134. package/dist/utilities/props.d.ts +13 -0
  135. package/dist/utilities/props.js +83 -0
  136. package/dist/utilities/scroll/lock.js +4 -3
  137. package/package.json +24 -24
  138. package/CHANGELOG-old.md +0 -14
  139. package/dist/components/Popover/tests/Popover.test.stories.d.ts +0 -39
  140. package/dist/components/Popover/tests/Popover.test.stories.js +0 -167
  141. package/dist/components/Slider/tests/Slider.test.stories.d.ts +0 -38
  142. package/dist/components/Slider/tests/Slider.test.stories.js +0 -150
  143. package/dist/components/_private/Flyout/Flyout.constants.d.ts +0 -3
  144. package/dist/components/_private/Flyout/Flyout.constants.js +0 -3
  145. package/dist/components/_private/Flyout/useFlyout.js +0 -211
  146. package/dist/components/_private/Flyout/utilities/calculatePosition.d.ts +0 -19
  147. package/dist/components/_private/Flyout/utilities/calculatePosition.js +0 -102
  148. package/dist/components/_private/Flyout/utilities/isFullyVisible.d.ts +0 -8
  149. package/dist/components/_private/Flyout/utilities/isFullyVisible.js +0 -16
  150. /package/dist/components/{_private/Flyout → Flyout}/Flyout.context.d.ts +0 -0
  151. /package/dist/components/{_private/Flyout → Flyout}/Flyout.context.js +0 -0
  152. /package/dist/components/{_private/Flyout → Flyout}/Flyout.d.ts +0 -0
  153. /package/dist/components/{_private/Flyout → Flyout}/Flyout.js +0 -0
  154. /package/dist/components/{_private/Flyout → Flyout}/Flyout.module.css +0 -0
  155. /package/dist/components/{_private/Flyout → Flyout}/Flyout.types.js +0 -0
  156. /package/dist/components/{_private/Flyout → Flyout}/FlyoutContent.d.ts +0 -0
  157. /package/dist/components/{_private/Flyout → Flyout}/FlyoutControlled.d.ts +0 -0
  158. /package/dist/components/{_private/Flyout → Flyout}/FlyoutTrigger.d.ts +0 -0
  159. /package/dist/components/{_private/Flyout → Flyout}/FlyoutTrigger.js +0 -0
  160. /package/dist/components/{_private/Flyout → Flyout}/FlyoutUncontrolled.d.ts +0 -0
  161. /package/dist/components/{_private/Flyout → Flyout}/FlyoutUncontrolled.js +0 -0
  162. /package/dist/components/{_private/Flyout → Flyout}/index.d.ts +0 -0
  163. /package/dist/components/{_private/Flyout → Flyout}/index.js +0 -0
  164. /package/dist/components/{_private/Flyout → Flyout}/utilities/cooldown.d.ts +0 -0
  165. /package/dist/components/{_private/Flyout → Flyout}/utilities/cooldown.js +0 -0
  166. /package/dist/components/{_private/Flyout → Flyout}/utilities/getPositionFallbacks.d.ts +0 -0
  167. /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,3 +0,0 @@
1
- export declare const mouseEnter = 800;
2
- export declare const mouseEnterShort = 100;
3
- export declare const mouseLeave = 150;
@@ -1,3 +0,0 @@
1
- export const mouseEnter = 800;
2
- export const mouseEnterShort = 100;
3
- export const mouseLeave = 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;