reshaped 3.1.5 → 3.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/dist/bundle.css +1 -1
  3. package/dist/bundle.d.ts +2 -0
  4. package/dist/bundle.js +10 -11
  5. package/dist/cjs/themes/_generator/definitions/reshaped.js +1 -1
  6. package/dist/cjs/themes/reshaped/theme.css +1 -1
  7. package/dist/components/Actionable/Actionable.d.ts +1 -1
  8. package/dist/components/Actionable/Actionable.js +2 -2
  9. package/dist/components/Actionable/Actionable.module.css +1 -1
  10. package/dist/components/Actionable/Actionable.types.d.ts +1 -0
  11. package/dist/components/Autocomplete/Autocomplete.js +12 -6
  12. package/dist/components/Button/Button.js +1 -1
  13. package/dist/components/Button/Button.module.css +1 -1
  14. package/dist/components/Card/Card.d.ts +1 -1
  15. package/dist/components/Card/Card.module.css +1 -1
  16. package/dist/components/Card/tests/Card.stories.d.ts +1 -1
  17. package/dist/components/Checkbox/Checkbox.module.css +1 -1
  18. package/dist/components/DropdownMenu/DropdownMenu.types.d.ts +1 -1
  19. package/dist/components/FormControl/FormControl.context.d.ts +2 -1
  20. package/dist/components/Grid/Grid.d.ts +6 -0
  21. package/dist/components/Grid/Grid.js +46 -0
  22. package/dist/components/Grid/Grid.module.css +1 -0
  23. package/dist/components/Grid/Grid.types.d.ts +31 -0
  24. package/dist/components/Grid/Grid.types.js +1 -0
  25. package/dist/components/Grid/index.d.ts +2 -0
  26. package/dist/components/Grid/index.js +1 -0
  27. package/dist/components/Grid/tests/Grid.stories.d.ts +18 -0
  28. package/dist/components/Grid/tests/Grid.stories.js +170 -0
  29. package/dist/components/Icon/Icon.module.css +1 -1
  30. package/dist/components/Link/Link.d.ts +1 -1
  31. package/dist/components/Loader/Loader.module.css +1 -1
  32. package/dist/components/Loader/Loader.types.d.ts +1 -1
  33. package/dist/components/Loader/tests/Loader.stories.js +5 -3
  34. package/dist/components/Modal/Modal.js +1 -1
  35. package/dist/components/Modal/Modal.module.css +1 -1
  36. package/dist/components/Overlay/Overlay.js +1 -1
  37. package/dist/components/Overlay/tests/Overlay.stories.js +1 -1
  38. package/dist/components/Popover/Popover.js +2 -4
  39. package/dist/components/Popover/Popover.types.d.ts +1 -1
  40. package/dist/components/Radio/Radio.module.css +1 -1
  41. package/dist/components/Resizable/Resizable.module.css +1 -1
  42. package/dist/components/ScrollArea/ScrollArea.js +1 -1
  43. package/dist/components/Select/Select.js +1 -1
  44. package/dist/components/Slider/Slider.module.css +1 -1
  45. package/dist/components/Slider/SliderControlled.js +2 -1
  46. package/dist/components/Switch/Switch.module.css +1 -1
  47. package/dist/components/Tabs/Tabs.d.ts +1 -1
  48. package/dist/components/Tabs/Tabs.module.css +1 -1
  49. package/dist/components/Tabs/TabsItem.d.ts +1 -1
  50. package/dist/components/Tabs/TabsItem.js +2 -3
  51. package/dist/components/Tabs/TabsList.js +1 -1
  52. package/dist/components/Tabs/tests/Tabs.stories.d.ts +15 -13
  53. package/dist/components/Tabs/tests/Tabs.stories.js +71 -8
  54. package/dist/components/Toast/ToastContainer.js +1 -2
  55. package/dist/components/Toast/ToastRegion.js +1 -1
  56. package/dist/components/Tooltip/Tooltip.js +1 -1
  57. package/dist/components/View/View.js +7 -3
  58. package/dist/components/View/View.module.css +1 -1
  59. package/dist/components/View/View.types.d.ts +2 -2
  60. package/dist/components/_private/Expandable/Expandable.js +9 -5
  61. package/dist/components/_private/Flyout/Flyout.module.css +1 -1
  62. package/dist/components/_private/Flyout/Flyout.types.d.ts +12 -3
  63. package/dist/components/_private/Flyout/FlyoutContent.js +1 -1
  64. package/dist/components/_private/Flyout/FlyoutControlled.js +34 -20
  65. package/dist/components/_private/Flyout/tests/Flyout.stories.d.ts +1 -0
  66. package/dist/components/_private/Flyout/tests/Flyout.stories.js +28 -18
  67. package/dist/components/_private/Flyout/useFlyout.d.ts +2 -1
  68. package/dist/components/_private/Flyout/useFlyout.js +46 -57
  69. package/dist/components/_private/Flyout/utilities/calculatePosition.js +16 -11
  70. package/dist/components/_private/Flyout/utilities/cooldown.d.ts +1 -1
  71. package/dist/components/_private/Flyout/utilities/cooldown.js +17 -5
  72. package/dist/components/_private/Flyout/utilities/getPositionFallbacks.d.ts +3 -0
  73. package/dist/components/_private/Flyout/utilities/getPositionFallbacks.js +39 -0
  74. package/dist/config/tailwind.d.ts +1 -1
  75. package/dist/hooks/_private/useOnClickOutside.js +3 -2
  76. package/dist/hooks/_private/useSingletonHotkeys.js +15 -12
  77. package/dist/hooks/_private/useSingletonKeyboardMode.js +1 -1
  78. package/dist/hooks/tests/useHotkeys.stories.js +3 -0
  79. package/dist/hooks/useDrag.js +2 -1
  80. package/dist/hooks/useScrollLock.js +12 -39
  81. package/dist/index.d.ts +2 -0
  82. package/dist/index.js +1 -0
  83. package/dist/styles/align/align.module.css +1 -0
  84. package/dist/styles/align/index.d.ts +3 -0
  85. package/dist/styles/align/index.js +10 -0
  86. package/dist/styles/justify/index.d.ts +3 -0
  87. package/dist/styles/justify/index.js +10 -0
  88. package/dist/styles/justify/justify.module.css +1 -0
  89. package/dist/styles/types.d.ts +2 -0
  90. package/dist/tests/ShadowDOM.stories.d.ts +6 -0
  91. package/dist/tests/ShadowDOM.stories.js +110 -0
  92. package/dist/themes/_generator/definitions/reshaped.js +1 -1
  93. package/dist/themes/_generator/tests/themes.stories.js +1 -1
  94. package/dist/themes/reshaped/theme.css +1 -1
  95. package/dist/utilities/a11y/TrapFocus.d.ts +1 -1
  96. package/dist/utilities/a11y/TrapFocus.js +14 -5
  97. package/dist/utilities/a11y/focus.d.ts +1 -1
  98. package/dist/utilities/a11y/focus.js +10 -5
  99. package/dist/utilities/a11y/index.d.ts +4 -0
  100. package/dist/utilities/a11y/index.js +3 -0
  101. package/dist/utilities/dom/flyout.d.ts +1 -0
  102. package/dist/utilities/dom/flyout.js +19 -0
  103. package/dist/utilities/dom/index.d.ts +3 -0
  104. package/dist/utilities/dom/index.js +3 -0
  105. package/dist/utilities/dom/shadowDom.d.ts +1 -0
  106. package/dist/utilities/dom/shadowDom.js +4 -0
  107. package/dist/utilities/dom/userSelect.d.ts +2 -0
  108. package/dist/utilities/dom/userSelect.js +6 -0
  109. package/dist/utilities/platform.d.ts +1 -0
  110. package/dist/utilities/platform.js +15 -0
  111. package/dist/utilities/scroll/disable.d.ts +7 -0
  112. package/dist/utilities/scroll/disable.js +13 -0
  113. package/dist/utilities/scroll/helpers.d.ts +1 -0
  114. package/dist/utilities/scroll/helpers.js +17 -0
  115. package/dist/utilities/scroll/index.d.ts +2 -0
  116. package/dist/utilities/scroll/index.js +2 -0
  117. package/dist/utilities/scroll/lock.d.ts +2 -0
  118. package/dist/utilities/scroll/lock.js +24 -0
  119. package/dist/utilities/scroll/lockSafari.d.ts +2 -0
  120. package/dist/utilities/scroll/lockSafari.js +31 -0
  121. package/dist/utilities/scroll/lockStandard.d.ts +2 -0
  122. package/dist/utilities/scroll/lockStandard.js +19 -0
  123. package/package.json +31 -29
  124. package/dist/utilities/dom.d.ts +0 -5
  125. package/dist/utilities/dom.js +0 -27
@@ -0,0 +1,10 @@
1
+ import { responsiveClassNames } from "../../utilities/helpers.js";
2
+ import s from "./align.module.css";
3
+ const getAlignStyles = (value) => {
4
+ if (!value)
5
+ return null;
6
+ return {
7
+ classNames: responsiveClassNames(s, "--align", value),
8
+ };
9
+ };
10
+ export default getAlignStyles;
@@ -0,0 +1,3 @@
1
+ import * as T from "../types";
2
+ declare const getJustifyStyles: T.StaticStyleUtility<T.Justify>;
3
+ export default getJustifyStyles;
@@ -0,0 +1,10 @@
1
+ import { responsiveClassNames } from "../../utilities/helpers.js";
2
+ import s from "./justify.module.css";
3
+ const getJustifyStyles = (value) => {
4
+ if (!value)
5
+ return null;
6
+ return {
7
+ classNames: responsiveClassNames(s, "--justify", value),
8
+ };
9
+ };
10
+ export default getJustifyStyles;
@@ -0,0 +1 @@
1
+ .--justify-start{justify-content:flex-start}.--justify-end{justify-content:flex-end}.--justify-center{justify-content:center}.--justify-space-between{justify-content:space-between}@media (--rs-viewport-m ){.--justify-start--m{justify-content:flex-start}.--justify-end--m{justify-content:flex-end}.--justify-center--m{justify-content:center}.--justify-space-between--m{justify-content:space-between}}@media (--rs-viewport-l ){.--justify-start--l{justify-content:flex-start}.--justify-end--l{justify-content:flex-end}.--justify-center--l{justify-content:center}.--justify-space-between--l{justify-content:space-between}}@media (--rs-viewport-xl ){.--justify-start--xl{justify-content:flex-start}.--justify-end--xl{justify-content:flex-end}.--justify-center--xl{justify-content:center}.--justify-space-between--xl{justify-content:space-between}}
@@ -1,6 +1,8 @@
1
1
  import React from "react";
2
2
  import * as G from "../types/global";
3
3
  export type TextAlign = "start" | "center" | "end";
4
+ export type Justify = "start" | "center" | "end" | "space-between";
5
+ export type Align = "start" | "center" | "end" | "stretch" | "baseline";
4
6
  export type Radius = "small" | "medium" | "large" | "circular" | "none";
5
7
  export type Position = "relative" | "absolute" | "fixed" | "sticky" | "static";
6
8
  export type BorderColor = "neutral" | "neutral-faded" | "critical" | "critical-faded" | "warning" | "warning-faded" | "positive" | "positive-faded" | "primary" | "primary-faded" | "disabled" | "brand" | "transparent";
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ declare const _default: {
3
+ title: string;
4
+ };
5
+ export default _default;
6
+ export declare const behavior: () => React.JSX.Element;
@@ -0,0 +1,110 @@
1
+ import React, { useEffect, useState, useRef, forwardRef } from "react";
2
+ import root from "react-shadow";
3
+ import { Example } from "../utilities/storybook/index.js";
4
+ import Autocomplete from "../components/Autocomplete/index.js";
5
+ import View from "../components/View/index.js";
6
+ import DropdownMenu from "../components/DropdownMenu/index.js";
7
+ import Reshaped from "../components/Reshaped/index.js";
8
+ import Select from "../components/Select/index.js";
9
+ import Button from "../components/Button/index.js";
10
+ import Tooltip from "../components/Tooltip/index.js";
11
+ export default {
12
+ title: "Meta/ShadowDOM",
13
+ };
14
+ const getStylesData = () => {
15
+ const sourceStylesContainer = document.head;
16
+ return Array.from(sourceStylesContainer.children).filter((x) => x instanceof HTMLStyleElement);
17
+ };
18
+ // Create a component to render inside the Shadow DOM
19
+ const ShadowDiv = forwardRef((props, ref) => {
20
+ const shadowRef = useRef(null);
21
+ // Load styles
22
+ useEffect(() => {
23
+ if (!shadowRef?.current)
24
+ return;
25
+ // Add styles to the shadow DOM
26
+ // const shadowEl = shadowRef?.current.shadowRoot;
27
+ const shadowEl = shadowRef?.current.shadowRoot;
28
+ if (!shadowEl)
29
+ return;
30
+ const sourceStylesContainer = document.head;
31
+ const observer = new MutationObserver(getStylesData);
32
+ observer.observe(sourceStylesContainer, {
33
+ characterData: true,
34
+ childList: true,
35
+ subtree: true,
36
+ });
37
+ let styleBlock = shadowEl.getElementById("custom-outer-style");
38
+ if (!styleBlock) {
39
+ styleBlock = document.createElement("span");
40
+ styleBlock.id = "custom-outer-style";
41
+ shadowEl.appendChild(styleBlock);
42
+ }
43
+ else {
44
+ styleBlock.innerHTML = "";
45
+ }
46
+ styleBlock.append(...getStylesData() // finds all <style> tags containing your web component ID
47
+ .map((x) => x.cloneNode(true)) // copies styles into the current instance of your web component. You might need to have multiple instances, so all of them need to track the styles.
48
+ );
49
+ return () => observer.disconnect();
50
+ }, []);
51
+ return (<Reshaped>
52
+ <root.div className="quote" ref={shadowRef}>
53
+ <div ref={ref}>
54
+ {/*
55
+ Adding padding here since otherwise mouseenter won't trigger on contents
56
+ when mouse is switching from outside the shadow dom
57
+ */}
58
+ <View padding={4}>{props.children}</View>
59
+ </div>
60
+ </root.div>
61
+ </Reshaped>);
62
+ });
63
+ // Main Component
64
+ const Component = () => {
65
+ const [valueAutoShadow, setValueAutoShadow] = useState("");
66
+ const [valueDropdownShadow, setValueDropdownShadow] = useState("");
67
+ const optionsAuto = ["Pizza", "Pie", "Ice-cream"];
68
+ const optionsDropdown = ["Turtle", "Cat", "Long-necked giraffe"];
69
+ const handleChangeAutoShadow = (args) => {
70
+ console.log("Autocomlete shadow value=", args);
71
+ setValueAutoShadow(args.value);
72
+ };
73
+ const handleChangeDropdownShadow = (val) => {
74
+ console.log("Dropdown shadow value=", val);
75
+ setValueDropdownShadow(val);
76
+ };
77
+ return (<View paddingBottom={50}>
78
+ <ShadowDiv>
79
+ <View gap={4} direction="row" wrap={false}>
80
+ <Autocomplete name="fruit-shadow" placeholder="Pick your food" value={valueAutoShadow} onChange={handleChangeAutoShadow}>
81
+ {optionsAuto.map((option) => (<Autocomplete.Item key={option} value={option} onClick={() => handleChangeAutoShadow({ value: option, name: "fruit-auto" })}>
82
+ {option}
83
+ </Autocomplete.Item>))}
84
+ </Autocomplete>
85
+
86
+ <DropdownMenu>
87
+ <DropdownMenu.Trigger>
88
+ {(attributes) => (<Select placeholder="Pick your animal" name="font" inputAttributes={attributes}>
89
+ {valueDropdownShadow}
90
+ </Select>)}
91
+ </DropdownMenu.Trigger>
92
+ <DropdownMenu.Content>
93
+ {optionsDropdown.map((option) => (<DropdownMenu.Item onClick={() => handleChangeDropdownShadow(option)} key={option}>
94
+ {option}
95
+ </DropdownMenu.Item>))}
96
+ </DropdownMenu.Content>
97
+ </DropdownMenu>
98
+
99
+ <Tooltip text="Tooltip for button">
100
+ {(attributes) => <Button attributes={attributes}>Hover me</Button>}
101
+ </Tooltip>
102
+ </View>
103
+ </ShadowDiv>
104
+ </View>);
105
+ };
106
+ export const behavior = () => (<Example>
107
+ <Example.Item title="base">
108
+ <Component />
109
+ </Example.Item>
110
+ </Example>);
@@ -123,7 +123,7 @@ const theme = {
123
123
  borderPositiveFaded: { hex: "#d0f3e2", hexDark: "#293b2f" },
124
124
  foregroundPositive: { hex: "#0d7544", hexDark: "#18ab66" },
125
125
  backgroundNeutral: { hex: "#dfe2ea", hexDark: "#494f60" },
126
- backgroundNeutralFaded: { hex: "#f1f2f6", hexDark: "#222835" },
126
+ backgroundNeutralFaded: { hex: "#f3f3f5", hexDark: "#222835" },
127
127
  borderNeutral: { hex: "#0000001f", hexDark: "#ffffff24" },
128
128
  borderNeutralFaded: { hex: "#0000001a", hexDark: "#ffffff17" },
129
129
  foregroundNeutral: { hex: "#14181f", hexDark: "#eff1f5" },
@@ -13,7 +13,7 @@ import Link from "../../../components/Link/index.js";
13
13
  import Text from "../../../components/Text/index.js";
14
14
  import { getThemeCSS, generateThemeColors, baseThemeDefinition } from "../../index.js";
15
15
  export default {
16
- title: "Themes",
16
+ title: "Meta/Themes",
17
17
  parameters: {
18
18
  iframe: { url: "https://reshaped.so/docs/tokens/theming/runtime-theming" },
19
19
  },
@@ -1 +1 @@
1
- [data-rs-theme=reshaped]{--rs-font-family-title:Inter,BlinkMacSystemFont,-apple-system,Roboto,Helvetica,Arial,sans-serif;--rs-font-family-body:Inter,BlinkMacSystemFont,-apple-system,Roboto,Helvetica,Arial,sans-serif;--rs-font-weight-regular:400;--rs-font-weight-medium:500;--rs-font-weight-semibold:600;--rs-font-weight-bold:700;--rs-font-weight-extrabold:800;--rs-font-weight-black:900;--rs-font-size-title-1:6rem;--rs-line-height-title-1:6.25rem;--rs-font-family-title-1:var(--rs-font-family-title);--rs-font-weight-title-1:var(--rs-font-weight-extrabold);--rs-letter-spacing-title-1:normal;--rs-font-size-title-2:5rem;--rs-line-height-title-2:5.25rem;--rs-font-family-title-2:var(--rs-font-family-title);--rs-font-weight-title-2:var(--rs-font-weight-extrabold);--rs-letter-spacing-title-2:normal;--rs-font-size-title-3:4rem;--rs-line-height-title-3:4.25rem;--rs-font-family-title-3:var(--rs-font-family-title);--rs-font-weight-title-3:var(--rs-font-weight-extrabold);--rs-letter-spacing-title-3:normal;--rs-font-size-title-4:3.5rem;--rs-line-height-title-4:3.75rem;--rs-font-family-title-4:var(--rs-font-family-title);--rs-font-weight-title-4:var(--rs-font-weight-bold);--rs-letter-spacing-title-4:normal;--rs-font-size-title-5:3rem;--rs-line-height-title-5:3.25rem;--rs-font-family-title-5:var(--rs-font-family-title);--rs-font-weight-title-5:var(--rs-font-weight-bold);--rs-letter-spacing-title-5:normal;--rs-font-size-title-6:2.25rem;--rs-line-height-title-6:2.5rem;--rs-font-family-title-6:var(--rs-font-family-title);--rs-font-weight-title-6:var(--rs-font-weight-bold);--rs-letter-spacing-title-6:normal;--rs-font-size-featured-1:2rem;--rs-line-height-featured-1:2.5rem;--rs-font-family-featured-1:var(--rs-font-family-body);--rs-letter-spacing-featured-1:normal;--rs-font-size-featured-2:1.5rem;--rs-line-height-featured-2:2rem;--rs-font-family-featured-2:var(--rs-font-family-body);--rs-letter-spacing-featured-2:normal;--rs-font-size-featured-3:1.25rem;--rs-line-height-featured-3:1.75rem;--rs-font-family-featured-3:var(--rs-font-family-body);--rs-letter-spacing-featured-3:normal;--rs-font-size-body-1:1.125rem;--rs-line-height-body-1:1.75rem;--rs-font-family-body-1:var(--rs-font-family-body);--rs-letter-spacing-body-1:normal;--rs-font-size-body-2:1rem;--rs-line-height-body-2:1.5rem;--rs-font-family-body-2:var(--rs-font-family-body);--rs-letter-spacing-body-2:normal;--rs-font-size-body-3:0.875rem;--rs-line-height-body-3:1.25rem;--rs-font-family-body-3:var(--rs-font-family-body);--rs-letter-spacing-body-3:normal;--rs-font-size-caption-1:0.75rem;--rs-line-height-caption-1:1rem;--rs-font-family-caption-1:var(--rs-font-family-body);--rs-letter-spacing-caption-1:normal;--rs-font-size-caption-2:0.625rem;--rs-line-height-caption-2:0.75rem;--rs-font-family-caption-2:var(--rs-font-family-body);--rs-letter-spacing-caption-2:normal;--rs-unit-base:4px;--rs-unit-x1:4px;--rs-unit-x2:8px;--rs-unit-x3:12px;--rs-unit-x4:16px;--rs-unit-x5:20px;--rs-unit-x6:24px;--rs-unit-x7:28px;--rs-unit-x8:32px;--rs-unit-x9:36px;--rs-unit-x10:40px;--rs-radius-small:4px;--rs-radius-medium:8px;--rs-radius-large:12px;--rs-color-brand:#5a58f2;--rs-color-white:#fff;--rs-color-black:#000;--rs-color-on-background-primary:#fff;--rs-color-on-background-critical:#fff;--rs-color-on-background-warning:#000;--rs-color-on-background-positive:#fff;--rs-color-on-brand:#fff;--rs-color-rgb-white:255,255,255;--rs-color-rgb-black:0,0,0;--rs-duration-fast:200ms;--rs-duration-medium:300ms;--rs-duration-slow:400ms;--rs-easing-standard:cubic-bezier(0.4,0,0.2,1);--rs-easing-accelerate:cubic-bezier(0.4,0,1,1);--rs-easing-decelerate:cubic-bezier(0,0,0.2,1);--rs-shadow-raised:0px 1px 5px -4px rgba(0,0,0,.5),0px 4px 8px 0px rgba(0,0,0,.05);--rs-shadow-overlay:0px 5px 10px 0px rgba(0,0,0,.05),0px 15px 25px 0px rgba(0,0,0,.07)}[data-rs-theme=reshaped][data-rs-color-mode=light]{--rs-color-background-primary:#5a58f2;--rs-color-background-primary-faded:#ecebfe;--rs-color-border-primary:#3b38ed;--rs-color-border-primary-faded:#dedcfb;--rs-color-foreground-primary:#4f4cf0;--rs-color-background-critical:#e22c2c;--rs-color-background-critical-faded:#fdeded;--rs-color-border-critical:#bf2424;--rs-color-border-critical-faded:#fadbdb;--rs-color-foreground-critical:#c42525;--rs-color-background-warning:#facc15;--rs-color-background-warning-faded:#fffae9;--rs-color-border-warning:#cfa90f;--rs-color-border-warning-faded:#faedbb;--rs-color-foreground-warning:#7b6305;--rs-color-background-positive:#118850;--rs-color-background-positive-faded:#edfdf5;--rs-color-border-positive:#0c6e40;--rs-color-border-positive-faded:#d0f3e2;--rs-color-foreground-positive:#0d7544;--rs-color-background-neutral:#dfe2ea;--rs-color-background-neutral-faded:#f1f2f6;--rs-color-border-neutral:#0000001f;--rs-color-border-neutral-faded:#0000001a;--rs-color-foreground-neutral:#14181f;--rs-color-foreground-neutral-faded:#5b667e;--rs-color-background-disabled:#eceef2;--rs-color-background-disabled-faded:#f5f6f9;--rs-color-border-disabled:#dfe2ea;--rs-color-foreground-disabled:#c6ccda;--rs-color-background-elevation-base:#fff;--rs-color-background-elevation-raised:#fff;--rs-color-background-elevation-overlay:#fff;--rs-color-background-page:#fff;--rs-color-background-page-faded:#f9f9fb;--rs-color-rgb-background-primary:90,88,242;--rs-color-rgb-background-primary-faded:236,235,254;--rs-color-rgb-background-critical:226,44,44;--rs-color-rgb-background-critical-faded:253,237,237;--rs-color-rgb-background-warning:250,204,21;--rs-color-rgb-background-warning-faded:255,250,233;--rs-color-rgb-background-positive:17,136,80;--rs-color-rgb-background-positive-faded:237,253,245;--rs-color-on-background-neutral:#000;--rs-color-rgb-background-neutral:223,226,234;--rs-color-rgb-background-neutral-faded:241,242,246;--rs-color-rgb-background-disabled:236,238,242;--rs-color-rgb-background-disabled-faded:245,246,249;--rs-color-rgb-background-elevation-base:255,255,255;--rs-color-rgb-background-elevation-raised:255,255,255;--rs-color-rgb-background-elevation-overlay:255,255,255;--rs-color-rgb-background-page:255,255,255;--rs-color-rgb-background-page-faded:249,249,251}[data-rs-theme=reshaped][data-rs-color-mode=dark]{--rs-color-background-primary:#524fea;--rs-color-background-primary-faded:#252544;--rs-color-border-primary:#8c8bf3;--rs-color-border-primary-faded:#323164;--rs-color-foreground-primary:#8b8af7;--rs-color-background-critical:#d02626;--rs-color-background-critical-faded:#3e1f1f;--rs-color-border-critical:#f46969;--rs-color-border-critical-faded:#582929;--rs-color-foreground-critical:#f36a6a;--rs-color-background-warning:#f1c512;--rs-color-background-warning-faded:#2c271f;--rs-color-border-warning:#b4920a;--rs-color-border-warning-faded:#3d3628;--rs-color-foreground-warning:#b4920c;--rs-color-background-positive:#14784a;--rs-color-background-positive-faded:#1f2a23;--rs-color-border-positive:#21ab6b;--rs-color-border-positive-faded:#293b2f;--rs-color-foreground-positive:#18ab66;--rs-color-background-neutral:#494f60;--rs-color-background-neutral-faded:#222835;--rs-color-border-neutral:#ffffff24;--rs-color-border-neutral-faded:#ffffff17;--rs-color-foreground-neutral:#eff1f5;--rs-color-foreground-neutral-faded:#c0c6d6;--rs-color-background-disabled:#1e212a;--rs-color-background-disabled-faded:#171921;--rs-color-border-disabled:#262a34;--rs-color-foreground-disabled:#434959;--rs-color-background-elevation-base:#15171e;--rs-color-background-elevation-raised:#191b23;--rs-color-background-elevation-overlay:#1c1f28;--rs-color-background-page:#0f1116;--rs-color-background-page-faded:#111319;--rs-color-rgb-background-primary:82,79,234;--rs-color-rgb-background-primary-faded:37,37,68;--rs-color-rgb-background-critical:208,38,38;--rs-color-rgb-background-critical-faded:62,31,31;--rs-color-rgb-background-warning:241,197,18;--rs-color-rgb-background-warning-faded:44,39,31;--rs-color-rgb-background-positive:20,120,74;--rs-color-rgb-background-positive-faded:31,42,35;--rs-color-on-background-neutral:#fff;--rs-color-rgb-background-neutral:73,79,96;--rs-color-rgb-background-neutral-faded:34,40,53;--rs-color-rgb-background-disabled:30,33,42;--rs-color-rgb-background-disabled-faded:23,25,33;--rs-color-rgb-background-elevation-base:21,23,30;--rs-color-rgb-background-elevation-raised:25,27,35;--rs-color-rgb-background-elevation-overlay:28,31,40;--rs-color-rgb-background-page:15,17,22;--rs-color-rgb-background-page-faded:17,19,25}
1
+ [data-rs-theme=reshaped]{--rs-font-family-title:Inter,BlinkMacSystemFont,-apple-system,Roboto,Helvetica,Arial,sans-serif;--rs-font-family-body:Inter,BlinkMacSystemFont,-apple-system,Roboto,Helvetica,Arial,sans-serif;--rs-font-weight-regular:400;--rs-font-weight-medium:500;--rs-font-weight-semibold:600;--rs-font-weight-bold:700;--rs-font-weight-extrabold:800;--rs-font-weight-black:900;--rs-font-size-title-1:6rem;--rs-line-height-title-1:6.25rem;--rs-font-family-title-1:var(--rs-font-family-title);--rs-font-weight-title-1:var(--rs-font-weight-extrabold);--rs-letter-spacing-title-1:normal;--rs-font-size-title-2:5rem;--rs-line-height-title-2:5.25rem;--rs-font-family-title-2:var(--rs-font-family-title);--rs-font-weight-title-2:var(--rs-font-weight-extrabold);--rs-letter-spacing-title-2:normal;--rs-font-size-title-3:4rem;--rs-line-height-title-3:4.25rem;--rs-font-family-title-3:var(--rs-font-family-title);--rs-font-weight-title-3:var(--rs-font-weight-extrabold);--rs-letter-spacing-title-3:normal;--rs-font-size-title-4:3.5rem;--rs-line-height-title-4:3.75rem;--rs-font-family-title-4:var(--rs-font-family-title);--rs-font-weight-title-4:var(--rs-font-weight-bold);--rs-letter-spacing-title-4:normal;--rs-font-size-title-5:3rem;--rs-line-height-title-5:3.25rem;--rs-font-family-title-5:var(--rs-font-family-title);--rs-font-weight-title-5:var(--rs-font-weight-bold);--rs-letter-spacing-title-5:normal;--rs-font-size-title-6:2.25rem;--rs-line-height-title-6:2.5rem;--rs-font-family-title-6:var(--rs-font-family-title);--rs-font-weight-title-6:var(--rs-font-weight-bold);--rs-letter-spacing-title-6:normal;--rs-font-size-featured-1:2rem;--rs-line-height-featured-1:2.5rem;--rs-font-family-featured-1:var(--rs-font-family-body);--rs-letter-spacing-featured-1:normal;--rs-font-size-featured-2:1.5rem;--rs-line-height-featured-2:2rem;--rs-font-family-featured-2:var(--rs-font-family-body);--rs-letter-spacing-featured-2:normal;--rs-font-size-featured-3:1.25rem;--rs-line-height-featured-3:1.75rem;--rs-font-family-featured-3:var(--rs-font-family-body);--rs-letter-spacing-featured-3:normal;--rs-font-size-body-1:1.125rem;--rs-line-height-body-1:1.75rem;--rs-font-family-body-1:var(--rs-font-family-body);--rs-letter-spacing-body-1:normal;--rs-font-size-body-2:1rem;--rs-line-height-body-2:1.5rem;--rs-font-family-body-2:var(--rs-font-family-body);--rs-letter-spacing-body-2:normal;--rs-font-size-body-3:0.875rem;--rs-line-height-body-3:1.25rem;--rs-font-family-body-3:var(--rs-font-family-body);--rs-letter-spacing-body-3:normal;--rs-font-size-caption-1:0.75rem;--rs-line-height-caption-1:1rem;--rs-font-family-caption-1:var(--rs-font-family-body);--rs-letter-spacing-caption-1:normal;--rs-font-size-caption-2:0.625rem;--rs-line-height-caption-2:0.75rem;--rs-font-family-caption-2:var(--rs-font-family-body);--rs-letter-spacing-caption-2:normal;--rs-unit-base:4px;--rs-unit-x1:4px;--rs-unit-x2:8px;--rs-unit-x3:12px;--rs-unit-x4:16px;--rs-unit-x5:20px;--rs-unit-x6:24px;--rs-unit-x7:28px;--rs-unit-x8:32px;--rs-unit-x9:36px;--rs-unit-x10:40px;--rs-radius-small:4px;--rs-radius-medium:8px;--rs-radius-large:12px;--rs-color-brand:#5a58f2;--rs-color-white:#fff;--rs-color-black:#000;--rs-color-on-background-primary:#fff;--rs-color-on-background-critical:#fff;--rs-color-on-background-warning:#000;--rs-color-on-background-positive:#fff;--rs-color-on-brand:#fff;--rs-color-rgb-white:255,255,255;--rs-color-rgb-black:0,0,0;--rs-duration-fast:200ms;--rs-duration-medium:300ms;--rs-duration-slow:400ms;--rs-easing-standard:cubic-bezier(0.4,0,0.2,1);--rs-easing-accelerate:cubic-bezier(0.4,0,1,1);--rs-easing-decelerate:cubic-bezier(0,0,0.2,1);--rs-shadow-raised:0px 1px 5px -4px rgba(0,0,0,.5),0px 4px 8px 0px rgba(0,0,0,.05);--rs-shadow-overlay:0px 5px 10px 0px rgba(0,0,0,.05),0px 15px 25px 0px rgba(0,0,0,.07)}[data-rs-theme=reshaped][data-rs-color-mode=light]{--rs-color-background-primary:#5a58f2;--rs-color-background-primary-faded:#ecebfe;--rs-color-border-primary:#3b38ed;--rs-color-border-primary-faded:#dedcfb;--rs-color-foreground-primary:#4f4cf0;--rs-color-background-critical:#e22c2c;--rs-color-background-critical-faded:#fdeded;--rs-color-border-critical:#bf2424;--rs-color-border-critical-faded:#fadbdb;--rs-color-foreground-critical:#c42525;--rs-color-background-warning:#facc15;--rs-color-background-warning-faded:#fffae9;--rs-color-border-warning:#cfa90f;--rs-color-border-warning-faded:#faedbb;--rs-color-foreground-warning:#7b6305;--rs-color-background-positive:#118850;--rs-color-background-positive-faded:#edfdf5;--rs-color-border-positive:#0c6e40;--rs-color-border-positive-faded:#d0f3e2;--rs-color-foreground-positive:#0d7544;--rs-color-background-neutral:#dfe2ea;--rs-color-background-neutral-faded:#f3f3f5;--rs-color-border-neutral:#0000001f;--rs-color-border-neutral-faded:#0000001a;--rs-color-foreground-neutral:#14181f;--rs-color-foreground-neutral-faded:#5b667e;--rs-color-background-disabled:#eceef2;--rs-color-background-disabled-faded:#f5f6f9;--rs-color-border-disabled:#dfe2ea;--rs-color-foreground-disabled:#c6ccda;--rs-color-background-elevation-base:#fff;--rs-color-background-elevation-raised:#fff;--rs-color-background-elevation-overlay:#fff;--rs-color-background-page:#fff;--rs-color-background-page-faded:#f9f9fb;--rs-color-rgb-background-primary:90,88,242;--rs-color-rgb-background-primary-faded:236,235,254;--rs-color-rgb-background-critical:226,44,44;--rs-color-rgb-background-critical-faded:253,237,237;--rs-color-rgb-background-warning:250,204,21;--rs-color-rgb-background-warning-faded:255,250,233;--rs-color-rgb-background-positive:17,136,80;--rs-color-rgb-background-positive-faded:237,253,245;--rs-color-on-background-neutral:#000;--rs-color-rgb-background-neutral:223,226,234;--rs-color-rgb-background-neutral-faded:243,243,245;--rs-color-rgb-background-disabled:236,238,242;--rs-color-rgb-background-disabled-faded:245,246,249;--rs-color-rgb-background-elevation-base:255,255,255;--rs-color-rgb-background-elevation-raised:255,255,255;--rs-color-rgb-background-elevation-overlay:255,255,255;--rs-color-rgb-background-page:255,255,255;--rs-color-rgb-background-page-faded:249,249,251}[data-rs-theme=reshaped][data-rs-color-mode=dark]{--rs-color-background-primary:#524fea;--rs-color-background-primary-faded:#252544;--rs-color-border-primary:#8c8bf3;--rs-color-border-primary-faded:#323164;--rs-color-foreground-primary:#8b8af7;--rs-color-background-critical:#d02626;--rs-color-background-critical-faded:#3e1f1f;--rs-color-border-critical:#f46969;--rs-color-border-critical-faded:#582929;--rs-color-foreground-critical:#f36a6a;--rs-color-background-warning:#f1c512;--rs-color-background-warning-faded:#2c271f;--rs-color-border-warning:#b4920a;--rs-color-border-warning-faded:#3d3628;--rs-color-foreground-warning:#b4920c;--rs-color-background-positive:#14784a;--rs-color-background-positive-faded:#1f2a23;--rs-color-border-positive:#21ab6b;--rs-color-border-positive-faded:#293b2f;--rs-color-foreground-positive:#18ab66;--rs-color-background-neutral:#494f60;--rs-color-background-neutral-faded:#222835;--rs-color-border-neutral:#ffffff24;--rs-color-border-neutral-faded:#ffffff17;--rs-color-foreground-neutral:#eff1f5;--rs-color-foreground-neutral-faded:#c0c6d6;--rs-color-background-disabled:#1e212a;--rs-color-background-disabled-faded:#171921;--rs-color-border-disabled:#262a34;--rs-color-foreground-disabled:#434959;--rs-color-background-elevation-base:#15171e;--rs-color-background-elevation-raised:#191b23;--rs-color-background-elevation-overlay:#1c1f28;--rs-color-background-page:#0f1116;--rs-color-background-page-faded:#111319;--rs-color-rgb-background-primary:82,79,234;--rs-color-rgb-background-primary-faded:37,37,68;--rs-color-rgb-background-critical:208,38,38;--rs-color-rgb-background-critical-faded:62,31,31;--rs-color-rgb-background-warning:241,197,18;--rs-color-rgb-background-warning-faded:44,39,31;--rs-color-rgb-background-positive:20,120,74;--rs-color-rgb-background-positive-faded:31,42,35;--rs-color-on-background-neutral:#fff;--rs-color-rgb-background-neutral:73,79,96;--rs-color-rgb-background-neutral-faded:34,40,53;--rs-color-rgb-background-disabled:30,33,42;--rs-color-rgb-background-disabled-faded:23,25,33;--rs-color-rgb-background-elevation-base:21,23,30;--rs-color-rgb-background-elevation-raised:25,27,35;--rs-color-rgb-background-elevation-overlay:28,31,40;--rs-color-rgb-background-page:15,17,22;--rs-color-rgb-background-page-faded:17,19,25}
@@ -7,7 +7,7 @@ type ReleaseOptions = {
7
7
  type TrapOptions = {
8
8
  onNavigateOutside?: () => void;
9
9
  includeTrigger?: boolean;
10
- initialFocusEl?: FocusableElement;
10
+ initialFocusEl?: FocusableElement | null;
11
11
  mode?: TrapMode;
12
12
  };
13
13
  declare class TrapFocus {
@@ -2,6 +2,7 @@ import Chain from "../Chain.js";
2
2
  import * as keys from "../../constants/keys.js";
3
3
  import TrapScreenReader from "./TrapScreenReader.js";
4
4
  import { getActiveElement, getFocusableElements, focusElement, getFocusData } from "./focus.js";
5
+ import { getShadowRoot } from "../dom/index.js";
5
6
  import { checkKeyboardMode } from "./keyboardMode.js";
6
7
  class TrapFocus {
7
8
  static chain = new Chain();
@@ -34,7 +35,7 @@ class TrapFocus {
34
35
  const isDown = navigationMode === "arrows" && key === keys.DOWN;
35
36
  const isPrev = (isBackTab && navigationMode === "tabs") || isUp;
36
37
  const isNext = (isNextTab && navigationMode === "tabs") || isDown;
37
- const isFocusedOnTrigger = getActiveElement() === this.trigger;
38
+ const isFocusedOnTrigger = getActiveElement(this.root) === this.trigger;
38
39
  const focusData = getFocusData({
39
40
  root: this.root,
40
41
  target: isPrev ? "prev" : "next",
@@ -61,15 +62,23 @@ class TrapFocus {
61
62
  return;
62
63
  focusElement(focusData.el, { pseudoFocus });
63
64
  };
64
- addListeners = () => document.addEventListener("keydown", this.handleKeyDown);
65
- removeListeners = () => document.removeEventListener("keydown", this.handleKeyDown);
65
+ addListeners = () => {
66
+ const shadowRoot = getShadowRoot(this.root);
67
+ const el = shadowRoot ?? document;
68
+ el.addEventListener("keydown", this.handleKeyDown);
69
+ };
70
+ removeListeners = () => {
71
+ const shadowRoot = getShadowRoot(this.root);
72
+ const el = shadowRoot ?? document;
73
+ el.removeEventListener("keydown", this.handleKeyDown);
74
+ };
66
75
  /**
67
76
  * Trap the focus, add observer and keyboard event listeners
68
77
  * and create a chain item
69
78
  */
70
79
  trap = (options = {}) => {
71
80
  const { mode = "dialog", includeTrigger, initialFocusEl } = options;
72
- const trigger = getActiveElement();
81
+ const trigger = getActiveElement(this.root);
73
82
  const focusable = getFocusableElements(this.root, {
74
83
  additionalElement: includeTrigger ? trigger : undefined,
75
84
  });
@@ -77,7 +86,7 @@ class TrapFocus {
77
86
  this.options = { ...options, pseudoFocus };
78
87
  this.trigger = trigger;
79
88
  this.mutationObserver = new MutationObserver(() => {
80
- const currentActiveElement = getActiveElement();
89
+ const currentActiveElement = getActiveElement(this.root);
81
90
  // Focus stayed inside the wrapper, no need to refocus
82
91
  if (this.root.contains(currentActiveElement))
83
92
  return;
@@ -1,6 +1,6 @@
1
1
  import type { FocusableElement } from "./types";
2
2
  export declare const focusableSelector = "a,button,input:not([type=\"hidden\"]),textarea,select,details,[tabindex]:not([tabindex=\"-1\"])";
3
- export declare const getActiveElement: () => HTMLButtonElement;
3
+ export declare const getActiveElement: (originEl?: HTMLElement | null) => HTMLButtonElement;
4
4
  export declare const focusElement: (el: FocusableElement, options?: {
5
5
  pseudoFocus?: boolean;
6
6
  }) => void;
@@ -1,11 +1,16 @@
1
+ import { getShadowRoot } from "../dom/index.js";
1
2
  const pseudoFocusAttribute = "data-rs-focus";
2
3
  export const focusableSelector = 'a,button,input:not([type="hidden"]),textarea,select,details,[tabindex]:not([tabindex="-1"])';
3
- export const getActiveElement = () => {
4
- const pseudoFocusedEl = document.querySelector(`[${pseudoFocusAttribute}]`);
5
- return (pseudoFocusedEl || document.activeElement);
4
+ export const getActiveElement = (originEl) => {
5
+ const shadowRoot = originEl ? getShadowRoot(originEl) : null;
6
+ const rootEl = shadowRoot ?? document;
7
+ const pseudoFocusedEl = rootEl.querySelector(`[${pseudoFocusAttribute}]`);
8
+ return (pseudoFocusedEl || rootEl.activeElement);
6
9
  };
7
10
  export const focusElement = (el, options) => {
8
- document.querySelector(`[${pseudoFocusAttribute}]`)?.removeAttribute(pseudoFocusAttribute);
11
+ const shadowRoot = getShadowRoot(el);
12
+ const rootEl = shadowRoot ?? document;
13
+ rootEl.querySelector(`[${pseudoFocusAttribute}]`)?.removeAttribute(pseudoFocusAttribute);
9
14
  if (options?.pseudoFocus) {
10
15
  el.setAttribute(pseudoFocusAttribute, "true");
11
16
  }
@@ -59,7 +64,7 @@ export const getFocusData = (args) => {
59
64
  const { root, target, options } = args;
60
65
  const focusable = getFocusableElements(root, { additionalElement: options?.additionalElement });
61
66
  const focusableLimit = focusable.length - 1;
62
- const currentElement = getActiveElement();
67
+ const currentElement = getActiveElement(root);
63
68
  const currentIndex = focusable.indexOf(currentElement);
64
69
  const positions = {
65
70
  next: currentIndex + 1,
@@ -0,0 +1,4 @@
1
+ export { focusableSelector, getActiveElement, focusNextElement, focusPreviousElement, focusFirstElement, focusLastElement, } from "./focus";
2
+ export { enableKeyboardMode, disableKeyboardMode, checkKeyboardMode } from "./keyboardMode";
3
+ export { default as TrapFocus } from "./TrapFocus";
4
+ export type { TrapMode, FocusableElement } from "./types";
@@ -0,0 +1,3 @@
1
+ export { focusableSelector, getActiveElement, focusNextElement, focusPreviousElement, focusFirstElement, focusLastElement, } from "./focus.js";
2
+ export { enableKeyboardMode, disableKeyboardMode, checkKeyboardMode } from "./keyboardMode.js";
3
+ export { default as TrapFocus } from "./TrapFocus.js";
@@ -0,0 +1 @@
1
+ export declare const getClosestFlyoutTarget: (el: HTMLElement | null, iteration?: number) => HTMLElement;
@@ -0,0 +1,19 @@
1
+ import { getShadowRoot } from "./shadowDom.js";
2
+ export const getClosestFlyoutTarget = (el, iteration = 0) => {
3
+ const style = el && window.getComputedStyle(el);
4
+ const overflowY = style?.overflowY;
5
+ const position = style?.position;
6
+ const isScrollable = overflowY?.includes("scroll");
7
+ const isFixed = position === "fixed" || position === "sticky";
8
+ // Only check shadow root on the first run
9
+ if (iteration === 0) {
10
+ const shadowRoot = getShadowRoot(el);
11
+ if (shadowRoot?.firstElementChild)
12
+ return shadowRoot.firstElementChild;
13
+ }
14
+ if (el === document.body || !el)
15
+ return document.body;
16
+ if ((isScrollable && el.scrollHeight > el.clientHeight) || isFixed)
17
+ return el;
18
+ return getClosestFlyoutTarget(el.parentElement, iteration + 1);
19
+ };
@@ -0,0 +1,3 @@
1
+ export { getClosestFlyoutTarget } from "./flyout";
2
+ export { getShadowRoot } from "./shadowDom";
3
+ export { enableUserSelect, disableUserSelect } from "./userSelect";
@@ -0,0 +1,3 @@
1
+ export { getClosestFlyoutTarget } from "./flyout.js";
2
+ export { getShadowRoot } from "./shadowDom.js";
3
+ export { enableUserSelect, disableUserSelect } from "./userSelect.js";
@@ -0,0 +1 @@
1
+ export declare const getShadowRoot: (el: HTMLElement | null) => ShadowRoot | null;
@@ -0,0 +1,4 @@
1
+ export const getShadowRoot = (el) => {
2
+ const rootNode = el?.getRootNode();
3
+ return rootNode instanceof ShadowRoot ? rootNode : null;
4
+ };
@@ -0,0 +1,2 @@
1
+ export declare const disableUserSelect: () => void;
2
+ export declare const enableUserSelect: () => void;
@@ -0,0 +1,6 @@
1
+ export const disableUserSelect = () => {
2
+ document.body.style.userSelect = "none";
3
+ };
4
+ export const enableUserSelect = () => {
5
+ document.body.style.userSelect = "";
6
+ };
@@ -0,0 +1 @@
1
+ export declare const isIOS: () => boolean;
@@ -0,0 +1,15 @@
1
+ const testPlatform = (re) => {
2
+ // Using experimentral and deprecated features here since that's the only way to detect platform consistently
3
+ const platform =
4
+ // @ts-ignore
5
+ window.navigator.userAgentData?.platform || window.navigator.platform;
6
+ return typeof window !== "undefined" ? re.test(platform) : false;
7
+ };
8
+ const isIPhone = () => testPlatform(/^iPhone/i);
9
+ const isMac = () => testPlatform(/^Mac/i);
10
+ const isIPad = () => {
11
+ return (testPlatform(/^iPad/i) ||
12
+ // iPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support.
13
+ (isMac() && navigator.maxTouchPoints > 1));
14
+ };
15
+ export const isIOS = () => isIPhone() || isIPad();
@@ -0,0 +1,7 @@
1
+ export declare const preventDefault: (e: Event) => void;
2
+ /**
3
+ * Prevent scrolling events for the cases when dragging elements
4
+ * without locking the page with overflow
5
+ */
6
+ export declare const disableScroll: () => void;
7
+ export declare const enableScroll: () => void;
@@ -0,0 +1,13 @@
1
+ export const preventDefault = (e) => e.preventDefault();
2
+ /**
3
+ * Prevent scrolling events for the cases when dragging elements
4
+ * without locking the page with overflow
5
+ */
6
+ export const disableScroll = () => {
7
+ window.addEventListener("wheel", preventDefault, { passive: false });
8
+ window.addEventListener("touchmove", preventDefault, { passive: false });
9
+ };
10
+ export const enableScroll = () => {
11
+ window.removeEventListener("wheel", preventDefault);
12
+ window.removeEventListener("touchmove", preventDefault);
13
+ };
@@ -0,0 +1 @@
1
+ export declare const getScrollbarWidth: () => number;
@@ -0,0 +1,17 @@
1
+ export const getScrollbarWidth = (() => {
2
+ let scrollbarWidth;
3
+ return () => {
4
+ if (scrollbarWidth)
5
+ return scrollbarWidth;
6
+ const scrollDiv = document.createElement("div");
7
+ scrollDiv.style.position = "absolute";
8
+ scrollDiv.style.top = "-9999px";
9
+ scrollDiv.style.width = "50px";
10
+ scrollDiv.style.height = "50px";
11
+ scrollDiv.style.overflow = "scroll";
12
+ document.body.appendChild(scrollDiv);
13
+ scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
14
+ document.body.removeChild(scrollDiv);
15
+ return scrollbarWidth;
16
+ };
17
+ })();
@@ -0,0 +1,2 @@
1
+ export { disableScroll, enableScroll } from "./disable";
2
+ export { lockScroll, unlockScroll } from "./lock";
@@ -0,0 +1,2 @@
1
+ export { disableScroll, enableScroll } from "./disable.js";
2
+ export { lockScroll, unlockScroll } from "./lock.js";
@@ -0,0 +1,2 @@
1
+ export declare const lockScroll: (cb?: () => void) => void;
2
+ export declare const unlockScroll: (cb?: () => void) => void;
@@ -0,0 +1,24 @@
1
+ import { isIOS } from "../platform.js";
2
+ import lockSafariScroll from "./lockSafari.js";
3
+ import lockStandardScroll from "./lockStandard.js";
4
+ let lockedCount = 0;
5
+ let reset = () => { };
6
+ export const lockScroll = (cb) => {
7
+ lockedCount += 1;
8
+ if (lockedCount > 1)
9
+ return;
10
+ if (isIOS()) {
11
+ reset = lockSafariScroll();
12
+ }
13
+ else {
14
+ reset = lockStandardScroll();
15
+ }
16
+ cb?.();
17
+ };
18
+ export const unlockScroll = (cb) => {
19
+ lockedCount -= 1;
20
+ if (lockedCount > 0)
21
+ return;
22
+ reset();
23
+ cb?.();
24
+ };
@@ -0,0 +1,2 @@
1
+ declare const lockSafariScroll: () => () => void;
2
+ export default lockSafariScroll;
@@ -0,0 +1,31 @@
1
+ let originalStyles = {};
2
+ const lockSafariScroll = () => {
3
+ const bodyStyle = document.body.style;
4
+ const offsetLeft = window.visualViewport?.offsetLeft || 0;
5
+ const offsetTop = window.visualViewport?.offsetTop || 0;
6
+ const scrollX = window.scrollX;
7
+ const scrollY = window.scrollY;
8
+ console.log(scrollY);
9
+ originalStyles = {
10
+ position: bodyStyle.position,
11
+ top: bodyStyle.top,
12
+ left: bodyStyle.left,
13
+ right: bodyStyle.right,
14
+ overflowX: bodyStyle.overflowX,
15
+ overflowY: bodyStyle.overflowY,
16
+ };
17
+ Object.assign(bodyStyle, {
18
+ position: "fixed",
19
+ top: `${-(scrollY - Math.floor(offsetTop))}px`,
20
+ left: `${-(scrollX - Math.floor(offsetLeft))}px`,
21
+ right: "0",
22
+ overflow: "hidden",
23
+ });
24
+ return () => {
25
+ Object.assign(bodyStyle, originalStyles);
26
+ window.scrollTo({ top: scrollY, left: scrollX, behavior: "instant" });
27
+ // window.scrollTo(scrollX, scrollY);
28
+ originalStyles = {};
29
+ };
30
+ };
31
+ export default lockSafariScroll;
@@ -0,0 +1,2 @@
1
+ declare const lockStandardScroll: () => () => void;
2
+ export default lockStandardScroll;
@@ -0,0 +1,19 @@
1
+ import { getScrollbarWidth } from "./helpers.js";
2
+ let originalBodyStyles = {};
3
+ const lockStandardScroll = () => {
4
+ const { body } = document;
5
+ const rect = body.getBoundingClientRect();
6
+ const isOverflowing = rect.left + rect.right < window.innerWidth;
7
+ originalBodyStyles.overflow = body.style.overflow;
8
+ body.style.overflow = "hidden";
9
+ if (isOverflowing) {
10
+ const scrollBarWidth = getScrollbarWidth();
11
+ originalBodyStyles.paddingRight = body.style.paddingRight;
12
+ body.style.paddingRight = `${scrollBarWidth}px`;
13
+ }
14
+ return () => {
15
+ Object.assign(body.style, originalBodyStyles);
16
+ originalBodyStyles = {};
17
+ };
18
+ };
19
+ export default lockStandardScroll;