reshaped 3.9.0-canary.9 → 3.9.1-canary.2

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 (87) hide show
  1. package/dist/bundle.css +1 -1
  2. package/dist/bundle.d.ts +2 -0
  3. package/dist/bundle.js +2 -2
  4. package/dist/components/Accordion/AccordionControlled.js +0 -1
  5. package/dist/components/Actionable/Actionable.d.ts +8 -3
  6. package/dist/components/Actionable/Actionable.js +17 -70
  7. package/dist/components/Actionable/Actionable.module.css +1 -1
  8. package/dist/components/Actionable/Actionable.types.d.ts +2 -36
  9. package/dist/components/Actionable/index.d.ts +2 -1
  10. package/dist/components/Badge/Badge.js +2 -2
  11. package/dist/components/Badge/Badge.module.css +1 -1
  12. package/dist/components/Badge/Badge.types.d.ts +1 -1
  13. package/dist/components/Button/Button.module.css +1 -1
  14. package/dist/components/Calendar/Calendar.module.css +1 -1
  15. package/dist/components/Calendar/Calendar.utils.js +6 -7
  16. package/dist/components/Card/Card.d.ts +2 -2
  17. package/dist/components/Card/Card.types.d.ts +5 -5
  18. package/dist/components/Carousel/Carousel.js +0 -1
  19. package/dist/components/Flyout/Flyout.constants.d.ts +1 -0
  20. package/dist/components/Flyout/Flyout.constants.js +1 -0
  21. package/dist/components/Flyout/Flyout.module.css +1 -1
  22. package/dist/components/Flyout/Flyout.types.d.ts +10 -8
  23. package/dist/components/Flyout/FlyoutContent.js +4 -49
  24. package/dist/components/Flyout/FlyoutControlled.js +94 -76
  25. package/dist/components/Flyout/FlyoutTrigger.js +3 -3
  26. package/dist/components/Flyout/useFlyout.d.ts +3 -4
  27. package/dist/components/Flyout/useFlyout.js +70 -88
  28. package/dist/components/Flyout/utilities/safeArea.d.ts +10 -0
  29. package/dist/components/Flyout/utilities/safeArea.js +100 -0
  30. package/dist/components/Grid/Grid.types.d.ts +4 -4
  31. package/dist/components/HiddenInput/HiddenInput.js +2 -3
  32. package/dist/components/Image/Image.js +1 -1
  33. package/dist/components/Modal/Modal.js +0 -3
  34. package/dist/components/Popover/Popover.module.css +1 -1
  35. package/dist/components/Reshaped/Reshaped.css +1 -1
  36. package/dist/components/ScrollArea/ScrollArea.js +6 -6
  37. package/dist/components/Select/Select.js +1 -1
  38. package/dist/components/Select/SelectCustomControlled.js +0 -1
  39. package/dist/components/Slider/SliderControlled.js +5 -4
  40. package/dist/components/Tabs/Tabs.module.css +1 -1
  41. package/dist/components/Tabs/Tabs.types.d.ts +3 -1
  42. package/dist/components/Tabs/TabsContext.d.ts +1 -0
  43. package/dist/components/Tabs/TabsControlled.js +2 -2
  44. package/dist/components/Tabs/TabsItem.js +2 -2
  45. package/dist/components/Tabs/TabsList.js +9 -5
  46. package/dist/components/Tabs/TabsPanel.js +1 -1
  47. package/dist/components/Text/Text.d.ts +1 -1
  48. package/dist/components/Text/Text.types.d.ts +3 -3
  49. package/dist/components/Toast/ToastContainer.js +0 -1
  50. package/dist/components/Tooltip/Tooltip.js +2 -2
  51. package/dist/components/Tooltip/Tooltip.module.css +1 -1
  52. package/dist/components/Tooltip/Tooltip.types.d.ts +1 -1
  53. package/dist/components/View/View.types.d.ts +4 -4
  54. package/dist/components/_private/Expandable/Expandable.js +1 -3
  55. package/dist/components/_private/Portal/Portal.js +0 -3
  56. package/dist/core/Actionable/Actionable.d.ts +4 -0
  57. package/dist/core/Actionable/Actionable.js +73 -0
  58. package/dist/core/Actionable/Actionable.types.d.ts +34 -0
  59. package/dist/core/Actionable/Actionable.types.js +1 -0
  60. package/dist/core/Actionable/index.d.ts +2 -0
  61. package/dist/core/Actionable/index.js +1 -0
  62. package/dist/hooks/_private/useDrag.js +0 -3
  63. package/dist/hooks/_private/usePrevious.js +0 -1
  64. package/dist/hooks/useOnClickOutside.js +8 -0
  65. package/dist/index.d.ts +2 -0
  66. package/dist/index.js +1 -0
  67. package/dist/types/global.d.ts +1 -1
  68. package/dist/utilities/a11y/TrapFocus.js +9 -3
  69. package/dist/utilities/dom/index.d.ts +0 -2
  70. package/dist/utilities/dom/index.js +0 -2
  71. package/dist/utilities/scroll/disable.js +4 -2
  72. package/package.json +7 -99
  73. package/README.md +0 -24
  74. package/dist/components/Flyout/utilities/calculatePosition.d.ts +0 -31
  75. package/dist/components/Flyout/utilities/calculatePosition.js +0 -178
  76. package/dist/components/Flyout/utilities/flyout.d.ts +0 -11
  77. package/dist/components/Flyout/utilities/flyout.js +0 -87
  78. package/dist/components/Flyout/utilities/getPositionFallbacks.d.ts +0 -3
  79. package/dist/components/Flyout/utilities/getPositionFallbacks.js +0 -39
  80. package/dist/components/Flyout/utilities/helpers.d.ts +0 -7
  81. package/dist/components/Flyout/utilities/helpers.js +0 -14
  82. package/dist/components/Flyout/utilities/isFullyVisible.d.ts +0 -12
  83. package/dist/components/Flyout/utilities/isFullyVisible.js +0 -22
  84. package/dist/utilities/dom/flyout.d.ts +0 -2
  85. package/dist/utilities/dom/flyout.js +0 -14
  86. package/dist/utilities/dom/userSelect.d.ts +0 -2
  87. package/dist/utilities/dom/userSelect.js +0 -6
@@ -0,0 +1,73 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { forwardRef } from "react";
4
+ import * as keys from "../../constants/keys.js";
5
+ import { classNames } from "../../utilities/props.js";
6
+ const Actionable = forwardRef((props, ref) => {
7
+ const { children, render, href, onClick, type, disabled, as, stopPropagation, className, attributes, } = props;
8
+ const rootAttributes = { ...attributes };
9
+ const hasClickHandler = onClick || attributes?.onClick;
10
+ const hasFocusHandler = attributes?.onFocus || attributes?.onBlur;
11
+ const isLink = Boolean(href || attributes?.href);
12
+ // Including attributes ref for the cases when event listeners are added through it
13
+ // To make sure it doesn't render a span
14
+ const isButton = Boolean(hasClickHandler || hasFocusHandler || type || attributes?.ref);
15
+ const renderedAsButton = !isLink && isButton && (!as || as === "button");
16
+ // Using any here to let TS save on type resolving, otherwise TS throws an error due to the type complexity
17
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
+ let TagName;
19
+ if (isLink) {
20
+ TagName = "a";
21
+ rootAttributes.href = disabled ? undefined : href || attributes?.href;
22
+ }
23
+ else if (renderedAsButton) {
24
+ TagName = "button";
25
+ rootAttributes.type = type || attributes?.type || "button";
26
+ rootAttributes.disabled = disabled || attributes?.disabled;
27
+ }
28
+ else if (isButton) {
29
+ const isFocusable = as === "label";
30
+ const simulateButton = !isFocusable || hasClickHandler || hasFocusHandler;
31
+ TagName = as || "span";
32
+ rootAttributes.role = simulateButton ? "button" : undefined;
33
+ rootAttributes.tabIndex = simulateButton ? 0 : undefined;
34
+ }
35
+ else {
36
+ TagName = as || "span";
37
+ }
38
+ const handlePress = (event) => {
39
+ if (disabled)
40
+ return;
41
+ if (stopPropagation)
42
+ event.stopPropagation();
43
+ onClick?.(event);
44
+ attributes?.onClick?.(event);
45
+ };
46
+ const handleKeyDown = (event) => {
47
+ const isSpace = event.key === keys.SPACE;
48
+ const isEnter = event.key === keys.ENTER;
49
+ if (!isSpace && !isEnter)
50
+ return;
51
+ if (rootAttributes.role !== "button")
52
+ return;
53
+ if (stopPropagation)
54
+ event.stopPropagation();
55
+ event.preventDefault();
56
+ handlePress(event);
57
+ };
58
+ const tagAttributes = {
59
+ ref: ref,
60
+ // rootAttributes can receive ref from Flyout
61
+ ...rootAttributes,
62
+ className: classNames(className),
63
+ onClick: handlePress,
64
+ onKeyDown: handleKeyDown,
65
+ "aria-disabled": disabled ? true : undefined,
66
+ children: children,
67
+ };
68
+ if (render)
69
+ return render(tagAttributes);
70
+ return _jsx(TagName, { ...tagAttributes });
71
+ });
72
+ Actionable.displayName = "Actionable";
73
+ export default Actionable;
@@ -0,0 +1,34 @@
1
+ import type React from "react";
2
+ import type * as G from "../../types/global";
3
+ export type AttributesRef = React.RefObject<HTMLButtonElement | null>;
4
+ type Attributes = G.Attributes<"button"> & Omit<React.JSX.IntrinsicElements["a"], keyof G.Attributes<"button">> & {
5
+ ref?: AttributesRef;
6
+ };
7
+ export type RenderAttributes = G.Attributes<"a"> & {
8
+ ref: React.RefObject<HTMLAnchorElement | null>;
9
+ children: React.ReactNode;
10
+ };
11
+ export type Props = {
12
+ /** Node for inserting the content */
13
+ children?: React.ReactNode;
14
+ /** Render a custom root element, useful for integrating with routers */
15
+ render?: (attributes: RenderAttributes) => React.ReactNode;
16
+ /** Callback when clicked, renders it as a button tag if href is not provided */
17
+ onClick?: (e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void;
18
+ /** URL, renders it as an anchor tag */
19
+ href?: string;
20
+ /** Type attribute, renders it as a button tag */
21
+ type?: React.ButtonHTMLAttributes<HTMLButtonElement>["type"];
22
+ /** Disable from user interaction */
23
+ disabled?: boolean;
24
+ /** Prevent the event from bubbling up to the parent */
25
+ stopPropagation?: boolean;
26
+ /** Render as a different element */
27
+ as?: keyof React.JSX.IntrinsicElements;
28
+ /** Additional classname for the root element */
29
+ className?: G.ClassName;
30
+ /** Additional attributes for the root element */
31
+ attributes?: Attributes;
32
+ };
33
+ export type Ref = HTMLButtonElement | HTMLAnchorElement;
34
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export { default } from "./Actionable";
2
+ export type { Props as ActionableProps, Ref as ActionableRef } from "./Actionable.types";
@@ -0,0 +1 @@
1
+ export { default } from "./Actionable.js";
@@ -4,7 +4,6 @@ import * as keys from "../../constants/keys.js";
4
4
  import useHandlerRef from "../useHandlerRef.js";
5
5
  import useHotkeys from "../useHotkeys.js";
6
6
  import useToggle from "../useToggle.js";
7
- import { disableUserSelect, enableUserSelect } from "../../utilities/dom/index.js";
8
7
  import { disableScroll, enableScroll } from "../../utilities/scroll/index.js";
9
8
  const useDrag = (cb, options) => {
10
9
  const { disabled, containerRef: passedContainerRef, orientation = "all" } = options || {};
@@ -76,7 +75,6 @@ const useDrag = (cb, options) => {
76
75
  const handleDragEnd = () => {
77
76
  triggerCompensationRef.current = { x: 0, y: 0 };
78
77
  toggle.deactivate();
79
- enableUserSelect();
80
78
  enableScroll();
81
79
  };
82
80
  document.addEventListener("touchmove", handleDrag, { passive: true });
@@ -103,7 +101,6 @@ const useDrag = (cb, options) => {
103
101
  y: resolvedEvent.clientY - triggerRect.y,
104
102
  };
105
103
  toggle.activate();
106
- disableUserSelect();
107
104
  disableScroll();
108
105
  };
109
106
  triggerEl.addEventListener("touchstart", handleStart, { passive: true });
@@ -12,7 +12,6 @@ const usePrevious = (value, clean = false) => {
12
12
  React.useEffect(() => {
13
13
  ref.current = clean ? copy(value) : value;
14
14
  }, [value, clean]);
15
- // eslint-disable-next-line react-hooks/refs
16
15
  return ref.current;
17
16
  };
18
17
  export default usePrevious;
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import * as keys from "../constants/keys.js";
2
3
  import useHandlerRef from "./useHandlerRef.js";
3
4
  const useOnClickOutside = (refs, handler, options) => {
4
5
  const { disabled } = options || {};
@@ -25,11 +26,18 @@ const useOnClickOutside = (refs, handler, options) => {
25
26
  }
26
27
  });
27
28
  };
29
+ const handleKeyDown = (event) => {
30
+ if (![keys.ENTER, keys.SPACE].includes(event.key))
31
+ return;
32
+ handleMouseDown(event);
33
+ };
28
34
  document.addEventListener("mousedown", handleMouseDown, { passive: true });
29
35
  document.addEventListener("touchstart", handleMouseDown, { passive: true });
36
+ document.addEventListener("keydown", handleKeyDown, { passive: true });
30
37
  return () => {
31
38
  document.removeEventListener("mousedown", handleMouseDown);
32
39
  document.removeEventListener("touchstart", handleMouseDown);
40
+ document.removeEventListener("keydown", handleKeyDown);
33
41
  };
34
42
  // eslint-disable-next-line react-hooks/exhaustive-deps
35
43
  }, [...refs]);
package/dist/index.d.ts CHANGED
@@ -110,6 +110,8 @@ export { default as Grid } from "./components/Grid";
110
110
  export type { GridProps, GridItemProps } from "./components/Grid";
111
111
  export { default as Hidden } from "./components/Hidden";
112
112
  export type { HiddenProps } from "./components/Hidden";
113
+ export { default as HiddenInput } from "./components/HiddenInput";
114
+ export type { HiddenInputProps } from "./components/HiddenInput";
113
115
  export { default as HiddenVisually } from "./components/HiddenVisually";
114
116
  export type { HiddenVisuallyProps } from "./components/HiddenVisually";
115
117
  export { default as Icon } from "./components/Icon";
package/dist/index.js CHANGED
@@ -57,6 +57,7 @@ export { default as Flyout } from "./components/Flyout/index.js";
57
57
  export { default as FormControl } from "./components/FormControl/index.js";
58
58
  export { default as Grid } from "./components/Grid/index.js";
59
59
  export { default as Hidden } from "./components/Hidden/index.js";
60
+ export { default as HiddenInput } from "./components/HiddenInput/index.js";
60
61
  export { default as HiddenVisually } from "./components/HiddenVisually/index.js";
61
62
  export { default as Icon } from "./components/Icon/index.js";
62
63
  export { default as Image } from "./components/Image/index.js";
@@ -7,7 +7,7 @@ export type ClassName = ClassNameValue | ClassNameValue[] | ClassName[];
7
7
  export type CSSVariable = `--${string}`;
8
8
  export type StyleAttribute = React.CSSProperties | (React.CSSProperties & Record<CSSVariable, string | number | undefined>);
9
9
  type DataAttributes = object | Record<`data-${string}`, string | boolean>;
10
- export type Attributes<TagName extends keyof React.JSX.IntrinsicElements = "div"> = React.JSX.IntrinsicElements[TagName] & DataAttributes & {
10
+ export type Attributes<TagName extends keyof React.JSX.IntrinsicElements | void = void> = (TagName extends keyof React.JSX.IntrinsicElements ? React.JSX.IntrinsicElements[TagName] : React.HTMLAttributes<HTMLElement>) & DataAttributes & {
11
11
  style?: StyleAttribute;
12
12
  };
13
13
  export type Viewport = "s" | "m" | "l" | "xl";
@@ -80,6 +80,10 @@ class TrapFocus {
80
80
  const el = shadowRoot ?? document;
81
81
  el.removeEventListener("keydown", this.#handleKeyDown);
82
82
  };
83
+ #isLast = () => {
84
+ const tailItem = _a.chain.tailId && _a.chain.get(_a.chain.tailId);
85
+ return tailItem && tailItem.data.#root === this.#root;
86
+ };
83
87
  /**
84
88
  * Trap the focus, add observer and keyboard event listeners
85
89
  * and create a chain item
@@ -98,6 +102,8 @@ class TrapFocus {
98
102
  this.#mutationObserver = new MutationObserver(() => {
99
103
  if (!this.#root)
100
104
  return;
105
+ if (!this.#isLast())
106
+ return;
101
107
  const currentActiveElement = getActiveElement(this.#root);
102
108
  // Focus stayed inside the wrapper, no need to refocus
103
109
  if (this.#root.contains(currentActiveElement))
@@ -117,10 +123,10 @@ class TrapFocus {
117
123
  this.#addListeners();
118
124
  if (mode === "dialog")
119
125
  this.#screenReaderTrap.trap();
120
- // Don't add back to the chain if we're traversing back
121
- const tailItem = _a.chain.tailId && _a.chain.get(_a.chain.tailId);
122
126
  const currentActiveElement = getActiveElement(this.#root);
123
- if (!tailItem || this.#root !== tailItem.data.#root) {
127
+ const isLastInChain = this.#isLast();
128
+ // Don't add back to the chain if we're traversing back
129
+ if (!isLastInChain) {
124
130
  this.#chainId = _a.chain.add(this);
125
131
  // If the focus was moved manually (e.g. with autoFocus) - keep it there
126
132
  if (!this.#root.contains(currentActiveElement)) {
@@ -1,5 +1,3 @@
1
- export { getRectFromCoordinates } from "./flyout";
2
1
  export { getShadowRoot } from "./shadowDom";
3
- export { enableUserSelect, disableUserSelect } from "./userSelect";
4
2
  export { findParent, findClosestScrollableContainer, findClosestPositionContainer } from "./find";
5
3
  export { triggerChangeEvent } from "./event";
@@ -1,5 +1,3 @@
1
- export { getRectFromCoordinates } from "./flyout.js";
2
1
  export { getShadowRoot } from "./shadowDom.js";
3
- export { enableUserSelect, disableUserSelect } from "./userSelect.js";
4
2
  export { findParent, findClosestScrollableContainer, findClosestPositionContainer } from "./find.js";
5
3
  export { triggerChangeEvent } from "./event.js";
@@ -4,10 +4,12 @@ export const preventDefault = (e) => e.preventDefault();
4
4
  * without locking the page with overflow
5
5
  */
6
6
  export const disableScroll = () => {
7
- window.addEventListener("wheel", preventDefault);
8
- window.addEventListener("touchmove", preventDefault);
7
+ window.addEventListener("wheel", preventDefault, { passive: false });
8
+ window.addEventListener("touchmove", preventDefault, { passive: false });
9
+ document.body.style.userSelect = "none";
9
10
  };
10
11
  export const enableScroll = () => {
11
12
  window.removeEventListener("wheel", preventDefault);
12
13
  window.removeEventListener("touchmove", preventDefault);
14
+ document.body.style.userSelect = "";
13
15
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reshaped",
3
3
  "description": "Professionally crafted design system in React & Figma for building products of any scale and complexity",
4
- "version": "3.9.0-canary.9",
4
+ "version": "3.9.1-canary.2",
5
5
  "license": "MIT",
6
6
  "email": "hello@reshaped.so",
7
7
  "homepage": "https://reshaped.so",
@@ -20,7 +20,8 @@
20
20
  ],
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "https://github.com/reshaped-ui/reshaped.git"
23
+ "url": "https://github.com/reshaped-ui/reshaped.git",
24
+ "directory": "packages/reshaped"
24
25
  },
25
26
  "bugs": {
26
27
  "url": "https://github.com/reshaped-ui/reshaped/issues"
@@ -77,107 +78,24 @@
77
78
  "browserslist": [
78
79
  "defaults and not IE 11"
79
80
  ],
80
- "devDependencies": {
81
- "@changesets/cli": "2.29.7",
82
- "@commitlint/cli": "20.1.0",
83
- "@commitlint/config-conventional": "20.0.0",
84
- "@commitlint/types": "20.0.0",
85
- "@eslint/js": "9.38.0",
86
- "@size-limit/preset-big-lib": "11.2.0",
87
- "@storybook/addon-a11y": "10.0.0",
88
- "@storybook/addon-docs": "10.0.0",
89
- "@storybook/addon-vitest": "10.0.0",
90
- "@storybook/react": "10.0.0",
91
- "@storybook/react-vite": "10.0.0",
92
- "@testing-library/user-event": "14.6.1",
93
- "@types/culori": "4.0.1",
94
- "@types/events": "3.0.3",
95
- "@types/node": "24.9.2",
96
- "@types/react": "19.2.2",
97
- "@types/react-dom": "19.2.2",
98
- "@vitejs/plugin-react": "5.1.0",
99
- "@vitest/browser": "4.0.4",
100
- "@vitest/browser-playwright": "4.0.4",
101
- "@vitest/coverage-istanbul": "4.0.4",
102
- "@vitest/coverage-v8": "4.0.4",
103
- "chromatic": "13.3.2",
104
- "eslint": "9.38.0",
105
- "eslint-config-prettier": "10.1.8",
106
- "eslint-import-resolver-typescript": "^4.4.4",
107
- "eslint-plugin-import": "2.32.0",
108
- "eslint-plugin-jsx-a11y": "6.10.2",
109
- "eslint-plugin-prettier": "5.5.4",
110
- "eslint-plugin-react": "7.37.5",
111
- "eslint-plugin-react-hooks": "7.0.1",
112
- "lefthook": "2.0.1",
113
- "playwright": "1.56.1",
114
- "postcss": "8.5.6",
115
- "postcss-cli": "11.0.1",
116
- "postcss-each": "1.1.0",
117
- "postcss-nested": "7.0.2",
118
- "prettier": "3.6.2",
119
- "react": "18",
120
- "react-dom": "18",
121
- "react-shadow": "20.6.0",
122
- "resolve-tspaths": "0.8.23",
123
- "size-limit": "11.2.0",
124
- "storybook": "10.0.0",
125
- "stylelint": "16.25.0",
126
- "stylelint-config-prettier": "9.0.5",
127
- "stylelint-config-standard": "39.0.1",
128
- "ts-node": "10.9.2",
129
- "typescript": "5.9.3",
130
- "typescript-eslint": "8.46.2",
131
- "vite": "7.1.12",
132
- "vite-tsconfig-paths": "5.1.4",
133
- "vitest": "4.0.4",
134
- "vitest-browser-react": "2.0.2"
135
- },
136
81
  "peerDependencies": {
137
82
  "postcss": "^8",
138
83
  "react": "^18 || ^19",
139
84
  "react-dom": "^18 || ^19"
140
85
  },
141
86
  "dependencies": {
142
- "@changesets/changelog-github": "0.5.1",
143
87
  "@csstools/postcss-global-data": "3.1.0",
144
88
  "chalk": "4.1.2",
145
89
  "commander": "14.0.2",
146
90
  "cssnano": "7.1.1",
147
91
  "csstype": "3.1.3",
148
92
  "culori": "4.0.2",
149
- "postcss-custom-media": "11.0.6"
150
- },
151
- "size-limit": [
152
- {
153
- "name": "Library / JS",
154
- "path": "dist/bundle.js",
155
- "webpack": false
156
- },
157
- {
158
- "name": "Library / CSS",
159
- "path": "dist/bundle.css",
160
- "webpack": false
161
- },
162
- {
163
- "name": "Theming / JS",
164
- "path": "dist/tests/themingWithoutDefinition.js",
165
- "webpack": true
166
- },
167
- {
168
- "name": "Theming with a default theme definition / JS",
169
- "path": "dist/tests/themingWithDefinition.js",
170
- "webpack": true
171
- }
172
- ],
173
- "engines": {
174
- "node": ">=22"
93
+ "postcss-custom-media": "11.0.6",
94
+ "@reshaped/utilities": "3.9.1-canary.2"
175
95
  },
176
96
  "scripts": {
177
- "dev": "storybook dev -p 3001 --disable-telemetry",
178
97
  "clean": "sh ./bin/clean.sh",
179
- "commit": "git-cz",
180
- "changeset": "changeset",
98
+ "dev": "storybook dev -p 3001 -c ../../.storybook --disable-telemetry",
181
99
  "build": "pnpm clean && pnpm build:esm && pnpm build:css && pnpm build:bundle",
182
100
  "build:themes": "node bin/cli.js theming --config dist/cli/theming/reshaped.config.js --output src/themes",
183
101
  "build:esm": "tsc -p tsconfig.esm.json && resolve-tspaths -p tsconfig.esm.json",
@@ -185,19 +103,9 @@
185
103
  "build:stories": "tsc -p tsconfig.stories.json && resolve-tspaths -p tsconfig.stories.json",
186
104
  "build:bundle": "vite build && cp dist/index.d.ts dist/bundle.d.ts",
187
105
  "build:size": "pnpm clean && pnpm build:esm && pnpm build:bundle",
188
- "build:storybook": "storybook build -o dist/app --disable-telemetry",
189
- "build:chromatic": "STORYBOOK_ENV=chromatic storybook build",
190
- "release": "sh ./bin/release.sh",
191
- "release:canary": "sh ./bin/release-canary.sh",
192
106
  "release:local": "pnpm build && pnpm pack --out reshaped-local.tgz",
193
- "chromatic": "chromatic -b build:chromatic --project-token=$(cat .chromatic)",
194
- "test:vrt": "pnpm chromatic",
195
- "test:vrt:turbo": "pnpm chromatic --only-changed",
196
107
  "test:browser": "vitest run --project=storybook",
197
108
  "test:unit": "vitest run --project=unit",
198
- "test:size": "size-limit",
199
- "lint": "pnpm lint:js && pnpm lint:css",
200
- "lint:js": "eslint './src/**/*.{ts,tsx}' --fix",
201
- "lint:css": "stylelint 'src/**/*.css'"
109
+ "test:size": "size-limit"
202
110
  }
203
111
  }
package/README.md DELETED
@@ -1,24 +0,0 @@
1
- # Reshaped
2
-
3
- <img width="2400" height="1260" alt="3 0 (1)" src="https://github.com/user-attachments/assets/ef632fe9-9446-430f-b87d-bebebe6fb595" />
4
- <br /><br />
5
-
6
- Reshaped is a library with professionally crafted React & Figma components for building beautiful products or starting your own design system.
7
-
8
- <br />
9
-
10
- ## Documentation
11
-
12
- To get started, check out the [Reshaped documentation](https://reshaped.so/docs/getting-started/overview).
13
-
14
- ## Contributing
15
-
16
- Read our [contribution guide](CONTRIBUTING.md) to learn about our principles, development process and testing.
17
-
18
- ## Maintainers
19
-
20
- - Dmitry Belyaev, [@blvdmitry](https://x.com/blvdmitry)
21
-
22
- ## License
23
-
24
- This project is licensed under the terms of the MIT license.
@@ -1,31 +0,0 @@
1
- import type * as T from "../Flyout.types";
2
- /**
3
- * Calculate styles for the current position
4
- */
5
- declare const calculatePosition: (args: {
6
- triggerBounds: DOMRect;
7
- flyoutBounds: {
8
- width: number;
9
- height: number;
10
- };
11
- passedContainer?: HTMLElement | null;
12
- containerBounds: DOMRect;
13
- } & Pick<T.Options, "position" | "rtl" | "width" | "contentGap" | "contentShift" | "fallbackAdjustLayout" | "fallbackMinWidth" | "fallbackMinHeight">) => {
14
- position: T.Position;
15
- styles: {
16
- left: string | null;
17
- right: string | null;
18
- top: string | null;
19
- bottom: string | null;
20
- transform: string;
21
- height: string | null;
22
- width: string | null;
23
- };
24
- boundaries: {
25
- left: number;
26
- top: number;
27
- height: number;
28
- width: number;
29
- };
30
- };
31
- export default calculatePosition;
@@ -1,178 +0,0 @@
1
- import { getRTLPosition, centerBySize } from "./helpers.js";
2
- const SCREEN_OFFSET = 8;
3
- /**
4
- * Calculate styles for the current position
5
- */
6
- const calculatePosition = (args) => {
7
- const { triggerBounds, flyoutBounds, containerBounds, position: passedPosition, rtl, width: passedWidth, contentGap = 0, contentShift = 0, passedContainer, fallbackAdjustLayout, fallbackMinWidth, fallbackMinHeight, } = args;
8
- const isFullWidth = passedWidth === "full" || passedWidth === "100%";
9
- let left = 0;
10
- let top = 0;
11
- let bottom = null;
12
- let right = null;
13
- let height = undefined;
14
- let width = undefined;
15
- let position = passedPosition;
16
- if (rtl)
17
- position = getRTLPosition(position);
18
- if (isFullWidth || width === "trigger") {
19
- position = position.includes("top") ? "top" : "bottom";
20
- }
21
- const isHorizontalPosition = !!position.match(/^(start|end)/);
22
- // contentGap adds padding to the flyout to make sure it doesn't disapper while moving the mouse to the content
23
- // So its width/height is bigger than the visible part of the content
24
- const flyoutWidth = flyoutBounds.width + (isHorizontalPosition ? contentGap : 0);
25
- const flyoutHeight = flyoutBounds.height + (!isHorizontalPosition ? contentGap : 0);
26
- const triggerWidth = triggerBounds.width;
27
- const triggerHeight = triggerBounds.height;
28
- // Detect passed container scroll to sync the flyout position with it
29
- const containerX = passedContainer?.scrollLeft;
30
- const containerY = passedContainer?.scrollTop;
31
- const scrollX = containerX ?? window.scrollX;
32
- const scrollY = containerY ?? window.scrollY;
33
- const renderContainerHeight = passedContainer?.clientHeight ?? window.innerHeight;
34
- const renderContainerWidth = passedContainer?.clientWidth ?? window.innerWidth;
35
- // When rendering in the body, bottom bounds will be larrger than the viewport so we calculate it manually
36
- const containerBoundsBottom = passedContainer
37
- ? containerBounds.bottom
38
- : window.innerHeight - scrollY;
39
- // When inside a container, adjut position based on the container scroll since flyout is rendered outside the scroll area
40
- const relativeLeft = triggerBounds.left - containerBounds.left + (containerX || 0);
41
- const relativeRight = containerBounds.right - triggerBounds.right - (containerX || 0);
42
- const relativeTop = triggerBounds.top - containerBounds.top + (containerY || 0);
43
- const relativeBottom = containerBoundsBottom - triggerBounds.bottom - (containerY || 0);
44
- switch (position) {
45
- case "start":
46
- case "start-top":
47
- case "start-bottom":
48
- left = relativeLeft - flyoutWidth;
49
- right = relativeRight + triggerWidth;
50
- break;
51
- case "end":
52
- case "end-top":
53
- case "end-bottom":
54
- left = relativeLeft + triggerWidth;
55
- break;
56
- case "bottom":
57
- case "top":
58
- left = relativeLeft + centerBySize(triggerWidth, flyoutWidth) + contentShift;
59
- break;
60
- case "top-start":
61
- case "bottom-start":
62
- left = relativeLeft + contentShift;
63
- break;
64
- case "top-end":
65
- case "bottom-end":
66
- left = relativeLeft + triggerWidth - flyoutWidth + contentShift;
67
- right = relativeRight - contentShift;
68
- break;
69
- default:
70
- break;
71
- }
72
- switch (position) {
73
- case "top":
74
- case "top-start":
75
- case "top-end":
76
- top = relativeTop - flyoutHeight;
77
- bottom = relativeBottom + triggerHeight;
78
- break;
79
- case "bottom":
80
- case "bottom-start":
81
- case "bottom-end":
82
- top = relativeTop + triggerHeight;
83
- break;
84
- case "start":
85
- case "end":
86
- top = relativeTop + centerBySize(triggerHeight, flyoutHeight) + contentShift;
87
- break;
88
- case "start-top":
89
- case "end-top":
90
- top = relativeTop + contentShift;
91
- break;
92
- case "start-bottom":
93
- case "end-bottom":
94
- top = relativeTop + triggerHeight - flyoutHeight + contentShift;
95
- bottom = relativeBottom - contentShift;
96
- break;
97
- default:
98
- break;
99
- }
100
- if (fallbackAdjustLayout) {
101
- const getOverflow = () => {
102
- return {
103
- top: -top + scrollY + SCREEN_OFFSET,
104
- bottom: top + flyoutHeight + SCREEN_OFFSET - scrollY - renderContainerHeight,
105
- left: -left + scrollX + SCREEN_OFFSET,
106
- right: left + flyoutWidth + SCREEN_OFFSET - scrollX - renderContainerWidth,
107
- };
108
- };
109
- const overflow = getOverflow();
110
- if (isHorizontalPosition) {
111
- if (overflow.top > 0) {
112
- top = SCREEN_OFFSET + scrollY;
113
- if (bottom !== null)
114
- bottom = bottom - overflow.top;
115
- }
116
- else if (overflow.bottom > 0) {
117
- top = top - overflow.bottom;
118
- }
119
- }
120
- else {
121
- if (overflow.left > 0) {
122
- left = SCREEN_OFFSET + scrollX;
123
- if (right !== null)
124
- right = right - overflow.left;
125
- }
126
- else if (overflow.right > 0) {
127
- left = left - overflow.right;
128
- }
129
- }
130
- const updatedOverflow = getOverflow();
131
- if (updatedOverflow.top > 0) {
132
- height = Math.max(fallbackMinHeight ? parseInt(fallbackMinHeight) : 0, flyoutHeight - updatedOverflow.top);
133
- top = top + (flyoutHeight - height);
134
- }
135
- else if (updatedOverflow.bottom > 0) {
136
- height = Math.max(fallbackMinHeight ? parseInt(fallbackMinHeight) : 0, flyoutHeight - updatedOverflow.bottom);
137
- if (bottom !== null)
138
- bottom = bottom + (flyoutHeight - height);
139
- }
140
- if (updatedOverflow.left > 0) {
141
- width = Math.max(fallbackMinWidth ? parseInt(fallbackMinWidth) : 0, flyoutWidth - updatedOverflow.left);
142
- left = left + (flyoutWidth - width);
143
- }
144
- else if (updatedOverflow.right > 0) {
145
- width = Math.max(fallbackMinWidth ? parseInt(fallbackMinWidth) : 0, flyoutWidth - updatedOverflow.right);
146
- if (right !== null)
147
- right = right + (flyoutWidth - width);
148
- }
149
- }
150
- if (isFullWidth) {
151
- left = SCREEN_OFFSET;
152
- width = window.innerWidth - SCREEN_OFFSET * 2;
153
- }
154
- else if (passedWidth === "trigger") {
155
- width = triggerBounds.width;
156
- }
157
- const translateX = right !== null ? -right : left;
158
- const translateY = bottom !== null ? -bottom : top;
159
- return {
160
- position,
161
- styles: {
162
- left: right === null ? "0px" : null,
163
- right: right === null ? null : "0px",
164
- top: bottom === null ? "0px" : null,
165
- bottom: bottom === null ? null : "0px",
166
- transform: `translate(${translateX}px, ${translateY}px)`,
167
- height: height !== undefined ? `${height}px` : null,
168
- width: width !== undefined ? `${width}px` : (passedWidth ?? null),
169
- },
170
- boundaries: {
171
- left,
172
- top,
173
- height: height ?? Math.ceil(flyoutHeight),
174
- width: width ?? Math.ceil(flyoutWidth),
175
- },
176
- };
177
- };
178
- export default calculatePosition;