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,21 +1,21 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React from "react";
4
- import { classNames } from "../../utilities/helpers.js";
4
+ import { classNames } from "../../utilities/props.js";
5
5
  import Theme from "../Theme/index.js";
6
6
  import Text from "../Text/index.js";
7
7
  import { getPrecision } from "./Slider.utilities.js";
8
8
  import s from "./Slider.module.css";
9
9
  const SliderThumb = React.forwardRef((props, ref) => {
10
- const { name, value, disabled, active, position, max, min, step, onChange, onDragStart, renderValue, tooltipRef, orientation, } = props;
10
+ const { name, value, disabled, active, position, max, min, step, onChange, onDragStart, renderValue, tooltipRef, inputRef, orientation, } = props;
11
11
  const id = React.useId();
12
12
  const thumbClassNames = classNames(s.thumb, active && s["thumb--active"]);
13
13
  const precision = getPrecision(step);
14
14
  const tooltipValue = renderValue ? renderValue({ value }) : value.toFixed(precision);
15
15
  const handleChange = (e) => {
16
- onChange(+e.target.value);
16
+ onChange(+e.target.value, { native: true });
17
17
  };
18
- return (_jsxs(_Fragment, { children: [_jsx("input", { className: s.input, type: "range", name: name, value: value, onChange: handleChange, disabled: disabled, max: max, min: min, step: step, "aria-labelledby": id, "aria-orientation": orientation }), _jsx("div", { ref: ref, className: thumbClassNames, onMouseDown: onDragStart, onTouchStart: onDragStart, style: { "--ts-slider-thumb-position": `${position}%` }, id: id, "aria-hidden": "true", children: renderValue !== false && (_jsx(Theme, { colorMode: "inverted", children: _jsx(Text, { variant: "caption-1", weight: "medium", className: s.tooltip, attributes: { ref: tooltipRef }, children: tooltipValue }) })) })] }));
18
+ return (_jsxs(_Fragment, { children: [_jsx("input", { className: s.input, type: "range", name: name, value: value, onChange: handleChange, disabled: disabled, max: max, min: min, step: step, "aria-labelledby": id, "aria-orientation": orientation, ref: inputRef }), _jsx("div", { ref: ref, className: thumbClassNames, onMouseDown: onDragStart, onTouchStart: onDragStart, style: { "--ts-slider-thumb-position": `${position}%` }, id: id, "aria-hidden": "true", children: renderValue !== false && (_jsx(Theme, { colorMode: "inverted", children: _jsx(Text, { variant: "caption-1", weight: "medium", className: s.tooltip, attributes: { ref: tooltipRef }, children: tooltipValue }) })) })] }));
19
19
  });
20
20
  SliderThumb.displayName = "SliderThumb";
21
21
  export default SliderThumb;
@@ -2,6 +2,7 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import React from "react";
4
4
  import SliderControlled from "./SliderControlled.js";
5
+ const normalizeValue = (value, min, max) => Math.min(Math.max(value, min), max);
5
6
  const SliderUncontrolled = (props) => {
6
7
  const { min, max, onChange, range } = props;
7
8
  const defaultMinValue = ("defaultMinValue" in props && props.defaultMinValue !== undefined && props.defaultMinValue) ||
@@ -10,8 +11,8 @@ const SliderUncontrolled = (props) => {
10
11
  const defaultMaxValue = ("defaultMaxValue" in props && props.defaultMaxValue !== undefined && props.defaultMaxValue) ||
11
12
  ("defaultValue" in props && props.defaultValue !== undefined && props.defaultValue) ||
12
13
  (range ? max : min);
13
- const [minValue, setMinValue] = React.useState(defaultMinValue);
14
- const [maxValue, setMaxValue] = React.useState(defaultMaxValue);
14
+ const [minValue, setMinValue] = React.useState(normalizeValue(defaultMinValue, min, max));
15
+ const [maxValue, setMaxValue] = React.useState(normalizeValue(defaultMaxValue, min, max));
15
16
  const handleSingleChange = (args) => {
16
17
  if (range)
17
18
  return;
@@ -1,6 +1,9 @@
1
+ import React from "react";
2
+ import { StoryObj } from "@storybook/react";
3
+ import { Mock } from "@storybook/test";
1
4
  declare const _default: {
2
5
  title: string;
3
- component: import("react").FC<import("./..").SliderProps>;
6
+ component: React.FC<import("./..").SliderProps>;
4
7
  parameters: {
5
8
  iframe: {
6
9
  url: string;
@@ -8,10 +11,37 @@ declare const _default: {
8
11
  };
9
12
  };
10
13
  export default _default;
11
- export declare const base: () => import("react").JSX.Element;
12
- export declare const direction: () => import("react").JSX.Element;
13
- export declare const step: () => import("react").JSX.Element;
14
- export declare const boundaries: () => import("react").JSX.Element;
15
- export declare const status: () => import("react").JSX.Element;
16
- export declare const customRender: () => import("react").JSX.Element;
17
- export declare const testModal: () => import("react").JSX.Element;
14
+ export declare const base: StoryObj;
15
+ export declare const orientation: {
16
+ name: string;
17
+ render: () => React.JSX.Element;
18
+ };
19
+ export declare const minMax: StoryObj;
20
+ export declare const step: StoryObj;
21
+ export declare const disabled: StoryObj;
22
+ export declare const renderValue: StoryObj;
23
+ export declare const defaultValue: StoryObj<{
24
+ handleChange: Mock;
25
+ handleChangeCommit: Mock;
26
+ }>;
27
+ export declare const value: StoryObj<{
28
+ handleChange: Mock;
29
+ handleChangeCommit: Mock;
30
+ }>;
31
+ export declare const rangeDefaultValue: StoryObj<{
32
+ handleChange: Mock;
33
+ handleChangeCommit: Mock;
34
+ }>;
35
+ export declare const rangeValue: StoryObj<{
36
+ handleChange: Mock;
37
+ handleChangeCommit: Mock;
38
+ }>;
39
+ export declare const className: StoryObj;
40
+ export declare const testForm: StoryObj<{
41
+ handleFormChange: Mock;
42
+ handleFormInit: Mock;
43
+ }>;
44
+ export declare const testSwipe: {
45
+ name: string;
46
+ render: () => React.JSX.Element;
47
+ };
@@ -1,7 +1,8 @@
1
+ import React from "react";
2
+ import { expect, fireEvent, fn } from "@storybook/test";
1
3
  import { Example } from "../../../utilities/storybook/index.js";
2
4
  import Slider from "../index.js";
3
5
  import View from "../../View/index.js";
4
- import FormControl from "../../FormControl/index.js";
5
6
  import Modal from "../../Modal/index.js";
6
7
  import useToggle from "../../../hooks/useToggle.js";
7
8
  export default {
@@ -13,59 +14,272 @@ export default {
13
14
  },
14
15
  },
15
16
  };
16
- export const base = () => (<Example>
17
- <Example.Item title="range">
18
- <Slider range name="slider" defaultMinValue={30} defaultMaxValue={100}/>
19
- </Example.Item>
20
- <div style={{ height: 2000 }}/>
21
- </Example>);
22
- export const direction = () => (<Example>
23
- <Example.Item title="vertical">
24
- <View height="200px">
25
- <Slider range name="slider" defaultMinValue={30} defaultMaxValue={100} orientation="vertical"/>
26
- </View>
17
+ export const base = {
18
+ name: "name, minName, maxName, range",
19
+ render: () => (<Example>
20
+ <Example.Item title="single, name">
21
+ <Slider name="slider-single" defaultValue={30}/>
22
+ </Example.Item>
23
+ <Example.Item title="range, name">
24
+ <Slider range name="slider-range" defaultMinValue={30} defaultMaxValue={85}/>
25
+ </Example.Item>
26
+ <Example.Item title="range, minName, maxName">
27
+ <Slider range minName="slider-min" maxName="slider-max" defaultMinValue={30} defaultMaxValue={85}/>
28
+ </Example.Item>
29
+ <div style={{ height: 2000 }}/>
30
+ </Example>),
31
+ play: ({ canvas }) => {
32
+ const inputs = canvas.getAllByRole("slider");
33
+ expect(inputs[0]).toHaveAttribute("name", "slider-single");
34
+ expect(inputs[1]).toHaveAttribute("name", "slider-range");
35
+ expect(inputs[2]).toHaveAttribute("name", "slider-range");
36
+ expect(inputs[3]).toHaveAttribute("name", "slider-min");
37
+ expect(inputs[4]).toHaveAttribute("name", "slider-max");
38
+ },
39
+ };
40
+ export const orientation = {
41
+ name: "orientation",
42
+ render: () => (<Example>
43
+ <Example.Item title="orientation: vertical">
44
+ <View height="200px">
45
+ <Slider range name="slider" defaultMinValue={30} defaultMaxValue={85} orientation="vertical"/>
46
+ </View>
47
+ </Example.Item>
27
48
  <View height="2000px"/>
28
- </Example.Item>
29
- </Example>);
30
- export const step = () => (<Example>
31
- <Example.Item title="float step">
32
- <Slider name="slider" defaultValue={30} step={0.01}/>
33
- </Example.Item>
34
- </Example>);
35
- export const boundaries = () => (<Example>
36
- <Example.Item title="min: 20, max: 30, value: 25">
37
- <Slider name="slider" defaultValue={25} min={20} max={30}/>
38
- </Example.Item>
39
- <Example.Item title="step: 10, value: 4, renders as 0">
40
- <Slider name="slider" defaultValue={4} step={10}/>
41
- </Example.Item>
42
- </Example>);
43
- export const status = () => (<Example>
44
- <Example.Item title="disabled">
45
- <Slider name="slider" defaultValue={30} disabled/>
46
- </Example.Item>
47
- <Example.Item title="step">
48
- <Slider range name="slider" defaultMinValue={30} defaultMaxValue={70} disabled/>
49
- </Example.Item>
50
- </Example>);
51
- export const customRender = () => (<Example>
52
- <Example.Item title="custom render">
53
- <FormControl>
54
- <FormControl.Label>Slider value</FormControl.Label>
55
- <Slider name="slider" defaultValue={30} renderValue={(args) => `$${args.value}`}/>
56
- </FormControl>
57
- </Example.Item>
49
+ </Example>),
50
+ };
51
+ export const minMax = {
52
+ name: "min, max",
53
+ render: () => (<Example>
54
+ <Example.Item title="min, max">
55
+ <Slider name="name" min={50} max={70} defaultValue={60}/>
56
+ </Example.Item>
57
+ <Example.Item title="min, max, value < min">
58
+ <Slider name="name" min={50} max={70} defaultValue={30}/>
59
+ </Example.Item>
60
+ <Example.Item title="min, max, value > max">
61
+ <Slider name="name" min={50} max={70} defaultValue={80}/>
62
+ </Example.Item>
63
+ </Example>),
64
+ play: async ({ canvas }) => {
65
+ const inputs = canvas.getAllByRole("slider");
66
+ expect(inputs[0]).toHaveAttribute("min", "50");
67
+ expect(inputs[0]).toHaveAttribute("max", "70");
68
+ expect(inputs[0]).toHaveValue("60");
69
+ fireEvent.change(inputs[0], { target: { value: 30 } });
70
+ expect(inputs[0]).toHaveValue("50");
71
+ fireEvent.change(inputs[0], { target: { value: 80 } });
72
+ expect(inputs[0]).toHaveValue("70");
73
+ expect(inputs[1]).toHaveValue("50");
74
+ expect(inputs[2]).toHaveValue("70");
75
+ },
76
+ };
77
+ export const step = {
78
+ name: "step",
79
+ render: () => (<Example>
80
+ <Example.Item title="step: 5">
81
+ <Slider name="slider" defaultValue={30} step={5}/>
82
+ </Example.Item>
83
+
84
+ <Example.Item title="step: 5, defaultValue: 31, rounded down to 30">
85
+ <Slider name="slider" defaultValue={31} step={5}/>
86
+ </Example.Item>
87
+
88
+ <Example.Item title="step: 0.01, float">
89
+ <Slider name="slider" defaultValue={30} step={0.01}/>
90
+ </Example.Item>
91
+ </Example>),
92
+ play: ({ canvas }) => {
93
+ const inputs = canvas.getAllByRole("slider");
94
+ expect(inputs[0]).toHaveValue("30");
95
+ fireEvent.change(inputs[0], { target: { value: 31 } });
96
+ expect(inputs[0]).toHaveValue("30");
97
+ fireEvent.change(inputs[0], { target: { value: 34 } });
98
+ expect(inputs[0]).toHaveValue("35");
99
+ expect(inputs[1]).toHaveValue("30");
100
+ },
101
+ };
102
+ export const disabled = {
103
+ name: "disabled",
104
+ render: () => (<Example>
105
+ <Example.Item title="disabled">
106
+ <Slider name="slider" defaultValue={30} disabled/>
107
+ </Example.Item>
58
108
 
59
- <Example.Item title="no tooltip">
60
- <FormControl>
61
- <FormControl.Label>Slider value</FormControl.Label>
62
- <Slider name="slider" defaultValue={30} renderValue={false}/>
63
- </FormControl>
64
- </Example.Item>
65
- </Example>);
66
- export const testModal = () => {
67
- const toggle = useToggle(true);
68
- return (<Modal active={toggle.active} onClose={toggle.deactivate} position="end">
69
- <Slider name="slider" defaultValue={30} renderValue={false}/>
70
- </Modal>);
109
+ <Example.Item title="disabled, range">
110
+ <Slider name="slider" range defaultMinValue={30} defaultMaxValue={80} disabled/>
111
+ </Example.Item>
112
+ </Example>),
113
+ play: async ({ canvas }) => {
114
+ const inputs = canvas.getAllByRole("slider");
115
+ expect(inputs[0]).toBeDisabled();
116
+ expect(inputs[1]).toBeDisabled();
117
+ },
118
+ };
119
+ export const renderValue = {
120
+ name: "renderValue",
121
+ render: () => (<Example>
122
+ <Example.Item title="renderValue: $">
123
+ <Slider name="name" defaultValue={50} renderValue={(args) => `$${args.value}`}/>
124
+ </Example.Item>
125
+ <Example.Item title="renderValue: false">
126
+ <Slider name="name" defaultValue={50} renderValue={false}/>
127
+ </Example.Item>
128
+ </Example>),
129
+ play: async ({ canvas }) => {
130
+ const tooltip = canvas.getByText("$50");
131
+ const hiddenTooltip = canvas.queryByText("50");
132
+ expect(tooltip).toBeInTheDocument();
133
+ expect(hiddenTooltip).not.toBeInTheDocument();
134
+ },
135
+ };
136
+ export const defaultValue = {
137
+ name: "defaultValue, onChange, onChangeCommit",
138
+ args: {
139
+ handleChange: fn(),
140
+ handleChangeCommit: fn(),
141
+ },
142
+ render: (args) => (<View paddingTop={10}>
143
+ <Slider name="test-name" defaultValue={50} onChange={args.handleChange} onChangeCommit={args.handleChangeCommit}/>
144
+ </View>),
145
+ play: async ({ canvas, args }) => {
146
+ const input = canvas.getByRole("slider");
147
+ expect(input).toHaveValue("50");
148
+ fireEvent.change(input, { target: { value: 51 } });
149
+ expect(args.handleChange).toHaveBeenCalledTimes(1);
150
+ expect(args.handleChange).toHaveBeenCalledWith({ value: 51, name: "test-name" });
151
+ expect(input).toHaveValue("51");
152
+ },
153
+ };
154
+ export const value = {
155
+ name: "value, onChange, onChangeCommit",
156
+ args: {
157
+ handleChange: fn(),
158
+ handleChangeCommit: fn(),
159
+ },
160
+ render: (args) => (<View paddingTop={10}>
161
+ <Slider name="test-name" value={50} onChange={args.handleChange} onChangeCommit={args.handleChangeCommit}/>
162
+ </View>),
163
+ play: async ({ canvas, args }) => {
164
+ const input = canvas.getByRole("slider");
165
+ expect(input).toHaveValue("50");
166
+ fireEvent.change(input, { target: { value: 51 } });
167
+ expect(args.handleChange).toHaveBeenCalledTimes(1);
168
+ expect(args.handleChange).toHaveBeenCalledWith({ value: 51, name: "test-name" });
169
+ expect(input).toHaveValue("50");
170
+ },
171
+ };
172
+ export const rangeDefaultValue = {
173
+ name: "range, defaultValue, onChange, onChangeCommit",
174
+ args: {
175
+ handleChange: fn(),
176
+ handleChangeCommit: fn(),
177
+ },
178
+ render: (args) => (<View paddingTop={10}>
179
+ <Slider range name="test-name" defaultMinValue={50} defaultMaxValue={70} onChange={args.handleChange} onChangeCommit={args.handleChangeCommit}/>
180
+ </View>),
181
+ play: async ({ canvas, args }) => {
182
+ const [minInput, maxInput] = canvas.getAllByRole("slider");
183
+ expect(minInput).toHaveValue("50");
184
+ expect(maxInput).toHaveValue("70");
185
+ fireEvent.change(minInput, { target: { value: 51 } });
186
+ expect(args.handleChange).toHaveBeenCalledTimes(1);
187
+ expect(args.handleChange).toHaveBeenCalledWith({
188
+ minValue: 51,
189
+ maxValue: 70,
190
+ name: "test-name",
191
+ minName: "test-name",
192
+ maxName: "test-name",
193
+ });
194
+ expect(minInput).toHaveValue("51");
195
+ expect(maxInput).toHaveValue("70");
196
+ },
197
+ };
198
+ export const rangeValue = {
199
+ name: "range, value, onChange, onChangeCommit, minName, maxName",
200
+ args: {
201
+ handleChange: fn(),
202
+ handleChangeCommit: fn(),
203
+ },
204
+ render: (args) => (<View paddingTop={10}>
205
+ <Slider range minName="test-name-min" maxName="test-name-max" minValue={50} maxValue={70} onChange={args.handleChange} onChangeCommit={args.handleChangeCommit}/>
206
+ </View>),
207
+ play: async ({ canvas, args }) => {
208
+ const [minInput, maxInput] = canvas.getAllByRole("slider");
209
+ expect(minInput).toHaveValue("50");
210
+ expect(maxInput).toHaveValue("70");
211
+ fireEvent.change(minInput, { target: { value: 51 } });
212
+ expect(args.handleChange).toHaveBeenCalledTimes(1);
213
+ expect(args.handleChange).toHaveBeenCalledWith({
214
+ minValue: 51,
215
+ maxValue: 70,
216
+ minName: "test-name-min",
217
+ maxName: "test-name-max",
218
+ });
219
+ expect(minInput).toHaveValue("50");
220
+ expect(maxInput).toHaveValue("70");
221
+ },
222
+ };
223
+ export const className = {
224
+ name: "className, attributes",
225
+ render: () => (<div data-testid="root">
226
+ <Slider name="name" className="test-classname" attributes={{ id: "test-id" }}/>
227
+ </div>),
228
+ play: async ({ canvas }) => {
229
+ const root = canvas.getByTestId("root").firstChild;
230
+ expect(root).toHaveClass("test-classname");
231
+ expect(root).toHaveAttribute("id", "test-id");
232
+ },
233
+ };
234
+ export const testForm = {
235
+ name: "test: form onChange",
236
+ args: {
237
+ handleFormChange: fn(),
238
+ handleFormInit: fn(),
239
+ },
240
+ render: (args) => {
241
+ const formRef = React.useRef(null);
242
+ const [data, setData] = React.useState([]);
243
+ const handleChange = (e) => {
244
+ const formData = new FormData(e.currentTarget);
245
+ const nextState = [...formData.entries()];
246
+ args.handleFormChange({ formData: nextState });
247
+ setData(nextState);
248
+ };
249
+ React.useEffect(() => {
250
+ const formData = new FormData(formRef.current);
251
+ const nextState = [...formData.entries()];
252
+ args.handleFormInit({ formData: nextState });
253
+ setData(nextState);
254
+ }, []);
255
+ return (<View paddingTop={10} gap={4}>
256
+ <form onChange={handleChange} ref={formRef}>
257
+ <Slider range minName="slider-min" maxName="slider-max" defaultMinValue={30} defaultMaxValue={50}/>
258
+ </form>
259
+
260
+ {data.map((v) => v.join(": ")).join(", ")}
261
+ </View>);
262
+ },
263
+ play: async () => {
264
+ /**
265
+ * Placeholder
266
+ *
267
+ * No way to test dragging here without calling fireEvent.change
268
+ * Which defeats the purpose of testing custom emitted events
269
+ *
270
+ * Test this behavior manually in Storybook by dragging the thumbs
271
+ */
272
+ },
273
+ };
274
+ export const testSwipe = {
275
+ name: "test: prevents parent swipe",
276
+ render: () => {
277
+ const toggle = useToggle(true);
278
+ return (<Modal active={toggle.active} onClose={toggle.deactivate} position="end">
279
+ <View gap={4}>
280
+ <Modal.Title>Modal</Modal.Title>
281
+ <Slider name="slider" defaultValue={30}/>
282
+ </View>
283
+ </Modal>);
284
+ },
71
285
  };
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from "react";
3
- import { responsivePropDependency } from "../../utilities/helpers.js";
3
+ import { responsivePropDependency } from "../../utilities/props.js";
4
4
  import Expandable from "../_private/Expandable/index.js";
5
5
  import View from "../View/index.js";
6
6
  import Text from "../Text/index.js";
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { classNames, responsiveClassNames, responsivePropDependency } from "../../utilities/helpers.js";
3
+ import { classNames, responsiveClassNames, responsivePropDependency } from "../../utilities/props.js";
4
4
  import { useFormControl } from "../FormControl/index.js";
5
5
  import Text from "../Text/index.js";
6
6
  import useElementId from "../../hooks/useElementId.js";
@@ -1,9 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import React from "react";
3
- import { classNames, responsiveVariables } from "../../utilities/helpers.js";
3
+ import { classNames, responsiveVariables } from "../../utilities/props.js";
4
4
  import getWidthStyles from "../../styles/width/index.js";
5
5
  import getMinWidthStyles from "../../styles/minWidth/index.js";
6
6
  import s from "./Table.module.css";
7
+ import useFadeSide from "../../hooks/_private/useFadeSide.js";
7
8
  const TableCellPrivate = (props) => {
8
9
  const { minWidth, rowSpan, colSpan, align, verticalAlign, tagName: TagName, padding, paddingInline, paddingBlock, children, className, attributes, } = props;
9
10
  const width = props.width === "auto" ? "0px" : props.width;
@@ -40,9 +41,11 @@ const TableHead = (props) => {
40
41
  };
41
42
  const Table = (props) => {
42
43
  const { children, border, columnBorder, className, attributes } = props;
43
- const rootClassNames = classNames(s.root, className, border && s["--border-outer"], columnBorder && s["--border-column"]);
44
+ const rootRef = React.useRef(null);
45
+ const fadeSide = useFadeSide(rootRef);
46
+ const rootClassNames = classNames(s.root, className, border && s["--border-outer"], columnBorder && s["--border-column"], (fadeSide === "start" || fadeSide === "both") && s["--fade-start"], (fadeSide === "end" || fadeSide === "both") && s["--fade-end"]);
44
47
  const [firstChild] = React.Children.toArray(children);
45
- return (_jsx("div", { ...attributes, className: rootClassNames, children: _jsx("table", { className: s.table, children: React.isValidElement(firstChild) &&
48
+ return (_jsx("div", { ...attributes, className: rootClassNames, ref: rootRef, children: _jsx("table", { className: s.table, children: React.isValidElement(firstChild) &&
46
49
  (firstChild.type === TableBody || firstChild.type === TableHead) ? (children) : (_jsx(TableBody, { children: children })) }) }));
47
50
  };
48
51
  Table.Cell = TableCell;
@@ -1 +1 @@
1
- .root{margin:0 calc(var(--rs-unit-x4) * -1);mask-image:linear-gradient(to right,transparent 0,#000 var(--rs-unit-x4),#000 calc(100% - var(--rs-unit-x4)),transparent 100%);overflow:auto;padding:0 var(--rs-unit-x4)}.table{border-collapse:separate;min-width:100%;overflow:hidden}.row{transition:background-color var(--rs-duration-fast) var(--rs-easing-standard)}.row[tabindex]{cursor:pointer}[data-rs-keyboard] .row:focus{box-shadow:var(--rs-focus-inset-shadow);outline:none;z-index:var(--rs-z-index-raised)}.cell{--rs-table-p-vertical-s:3;--rs-table-p-horizontal-s:4;padding:calc(var(--rs-unit-x1) * var(--rs-table-p-vertical-s)) calc(var(--rs-unit-x1) * var(--rs-table-p-horizontal-s));text-align:start;vertical-align:top}.cell:not(:last-child){padding-inline-end:0}.head+.body .row:first-child .cell,.row:not(:first-child) .cell{border-top:1px solid var(--rs-color-border-neutral-faded)}.cell--align-start{text-align:start}.cell--align-center{text-align:center}.cell--align-end{text-align:end}.cell--valign-start{vertical-align:top}.cell--valign-center{vertical-align:middle}.cell--valign-end{vertical-align:bottom}.cell--width-auto{white-space:nowrap}.--row-highlighted{background-color:rgba(var(--rs-color-rgb-background-neutral),24%)}.--border-outer .table{border:1px solid var(--rs-color-border-neutral-faded);border-radius:var(--rs-radius-medium)}.--border-column .cell:not(:first-child){border-inline-start:1px solid var(--rs-color-border-neutral-faded)}.--border-column .cell:not(:last-child){padding-inline-end:calc(var(--rs-unit-x1) * var(--rs-table-p-horizontal-s))}
1
+ @property --rs-table-fade-start{syntax:"<length>";initial-value:0;inherits:false}@property --rs-table-fade-end{syntax:"<length>";initial-value:0;inherits:false}.root{mask-image:linear-gradient(to right,transparent 0,#000 var(--rs-table-fade-start),#000 calc(100% - var(--rs-table-fade-end)),transparent 100%);overflow:auto;transition:var(--rs-duration-medium) var(--rs-easing-decelerate);transition-property:--rs-table-fade-start,--rs-table-fade-end}.table{border-collapse:separate;min-width:100%;overflow:hidden}.row{transition:background-color var(--rs-duration-fast) var(--rs-easing-standard)}.row[tabindex]{cursor:pointer}[data-rs-keyboard] .row:focus{box-shadow:var(--rs-focus-inset-shadow);outline:none;z-index:var(--rs-z-index-raised)}.cell{--rs-table-p-vertical-s:3;--rs-table-p-horizontal-s:4;padding:calc(var(--rs-unit-x1) * var(--rs-table-p-vertical-s)) calc(var(--rs-unit-x1) * var(--rs-table-p-horizontal-s));text-align:start;vertical-align:top}.cell:not(:last-child){padding-inline-end:0}.head+.body .row:first-child .cell,.row:not(:first-child) .cell{border-top:1px solid var(--rs-color-border-neutral-faded)}.cell--align-start{text-align:start}.cell--align-center{text-align:center}.cell--align-end{text-align:end}.cell--valign-start{vertical-align:top}.cell--valign-center{vertical-align:middle}.cell--valign-end{vertical-align:bottom}.cell--width-auto{white-space:nowrap}.--row-highlighted{background-color:rgba(var(--rs-color-rgb-background-neutral),24%)}.--border-outer .table{border:1px solid var(--rs-color-border-neutral-faded);border-radius:var(--rs-radius-medium)}.--border-column .cell:not(:first-child){border-inline-start:1px solid var(--rs-color-border-neutral-faded)}.--border-column .cell:not(:last-child){padding-inline-end:calc(var(--rs-unit-x1) * var(--rs-table-p-horizontal-s))}.--fade-start,[dir=rtl] .--fade-end{--rs-table-fade-start:var(--rs-unit-x4)}.--fade-end,[dir=rtl] .--fade-start{--rs-table-fade-end:var(--rs-unit-x4)}
@@ -4,13 +4,13 @@ export declare const TabsProvider: React.Provider<T.Context>;
4
4
  export declare const useTabs: (value?: string) => {
5
5
  panelId: string | undefined;
6
6
  buttonId: string | undefined;
7
+ variant?: "bordered" | "borderless" | "pills" | "pills-elevated" | undefined;
7
8
  name?: string | undefined;
9
+ direction?: "column" | "row" | undefined;
8
10
  onChange?: ((args: {
9
11
  value: string;
10
12
  name?: string;
11
13
  }) => void) | undefined;
12
- variant?: "bordered" | "borderless" | "pills" | "pills-elevated" | undefined;
13
- direction?: "column" | "row" | undefined;
14
14
  itemWidth?: "equal" | undefined;
15
15
  size: NonNullable<T.BaseProps["size"]>;
16
16
  value?: string;
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React from "react";
4
- import { classNames } from "../../utilities/helpers.js";
4
+ import { classNames } from "../../utilities/props.js";
5
5
  import HiddenInput from "../_private/HiddenInput/index.js";
6
6
  import Actionable from "../Actionable/index.js";
7
7
  import Icon from "../Icon/index.js";
@@ -1,11 +1,12 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React from "react";
4
- import { classNames, throttle } from "../../utilities/helpers.js";
4
+ import { classNames } from "../../utilities/props.js";
5
5
  import useRTL from "../../hooks/useRTL.js";
6
6
  import { focusNextElement, focusPreviousElement, focusFirstElement, focusLastElement, } from "../../utilities/a11y/index.js";
7
7
  import useIsomorphicLayoutEffect from "../../hooks/useIsomorphicLayoutEffect.js";
8
8
  import useHotkeys from "../../hooks/useHotkeys.js";
9
+ import useFadeSide from "../../hooks/_private/useFadeSide.js";
9
10
  import Actionable from "../Actionable/index.js";
10
11
  import Icon from "../Icon/index.js";
11
12
  import IconChevronRight from "../../icons/ChevronRight.js";
@@ -24,7 +25,7 @@ const TabsList = (props) => {
24
25
  const { children, className, attributes } = props;
25
26
  const { value, setDefaultValue, itemWidth, variant, name, direction, size, selection, setSelection, elActiveRef, elPrevActiveRef, elScrollableRef, } = useTabs();
26
27
  const [rtl] = useRTL();
27
- const [fadeSide, setFadeSide] = React.useState(null);
28
+ const fadeSide = useFadeSide(elScrollableRef);
28
29
  const rootClassNames = classNames(s.root, size && s[`--size-${size}`], direction && s[`--direction-${direction}`], itemWidth && s[`--item-width-${itemWidth}`], variant && s[`--variant-${variant}`], (fadeSide === "start" || fadeSide === "both") && s["--fade-start"], (fadeSide === "end" || fadeSide === "both") && s["--fade-end"], className);
29
30
  const selectorClassNames = classNames(s.selector, selection.status === "idle" && s["--selector-hidden"], selection.status === "animated" && s["--selector-animated"]);
30
31
  const handleNextClick = () => {
@@ -105,38 +106,6 @@ const TabsList = (props) => {
105
106
  return;
106
107
  setSelection({ ...selectionStyle, status: "animated" });
107
108
  }, [selection]);
108
- useIsomorphicLayoutEffect(() => {
109
- const elScrollable = elScrollableRef.current;
110
- if (!elScrollable || direction === "column")
111
- return;
112
- const updateArrowNav = () => {
113
- const isScrollable = elScrollable.clientWidth < elScrollable.scrollWidth;
114
- if (!isScrollable)
115
- setFadeSide(null);
116
- // scrollLeft in RTL starts from 1 instead of 0, so we compare values using this delta
117
- const scrollLeft = elScrollable.scrollLeft * (rtl ? -1 : 1);
118
- const cutOffStart = scrollLeft > 1;
119
- const cutOffEnd = scrollLeft + elScrollable.clientWidth < elScrollable.scrollWidth - 1;
120
- if (cutOffEnd && cutOffStart)
121
- return setFadeSide("both");
122
- if (cutOffStart)
123
- return setFadeSide("start");
124
- if (cutOffEnd)
125
- return setFadeSide("end");
126
- };
127
- const debouncedUpdateArrowNav = throttle(updateArrowNav, 16);
128
- // Use RaF when scroll to have scrollWidth calculated correctly on the first effect
129
- // For example: And edge case inside the complex flexbox layout
130
- requestAnimationFrame(() => {
131
- updateArrowNav();
132
- });
133
- window.addEventListener("resize", debouncedUpdateArrowNav);
134
- elScrollable.addEventListener("scroll", debouncedUpdateArrowNav);
135
- return () => {
136
- window.removeEventListener("resize", debouncedUpdateArrowNav);
137
- elScrollable.removeEventListener("scroll", debouncedUpdateArrowNav);
138
- };
139
- }, [rtl]);
140
109
  return (_jsxs("div", { ...attributes, className: rootClassNames, children: [_jsx("div", { className: s.inner, ref: elScrollableRef, children: _jsxs("div", { className: s.list, role: "tablist", ref: hotkeysRef, children: [React.Children.map(children, (child, index) => {
141
110
  if (!React.isValidElement(child))
142
111
  return null;
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { classNames } from "../../utilities/helpers.js";
3
+ import { classNames } from "../../utilities/props.js";
4
4
  import { useTabs } from "./TabsContext.js";
5
5
  import s from "./Tabs.module.css";
6
6
  const TabsPanel = (props) => {
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { classNames, responsiveClassNames } from "../../utilities/helpers.js";
2
+ import { classNames, responsiveClassNames } from "../../utilities/props.js";
3
3
  import getTextAlignStyles from "../../styles/textAlign/index.js";
4
4
  import s from "./Text.module.css";
5
5
  const tagMap = {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import React from "react";
4
- import { classNames, responsiveClassNames } from "../../utilities/helpers.js";
4
+ import { classNames, responsiveClassNames } from "../../utilities/props.js";
5
5
  import { useFormControl } from "../FormControl/index.js";
6
6
  import Aligner from "../_private/Aligner/index.js";
7
7
  import useElementId from "../../hooks/useElementId.js";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React from "react";
4
- import { classNames, responsiveClassNames, responsivePropDependency } from "../../utilities/helpers.js";
4
+ import { classNames, responsiveClassNames, responsivePropDependency } from "../../utilities/props.js";
5
5
  import useElementId from "../../hooks/useElementId.js";
6
6
  import { useFormControl } from "../FormControl/index.js";
7
7
  import Icon from "../Icon/index.js";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import React from "react";
4
- import { classNames } from "../../utilities/helpers.js";
4
+ import { classNames } from "../../utilities/props.js";
5
5
  import useIsomorphicLayoutEffect from "../../hooks/useIsomorphicLayoutEffect.js";
6
6
  import { ThemeContext } from "./Theme.context.js";
7
7
  import { getRootThemeEl } from "./Theme.utilities.js";
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from "react";
3
- import { classNames } from "../../utilities/helpers.js";
3
+ import { classNames } from "../../utilities/props.js";
4
4
  import View from "../View/index.js";
5
5
  import s from "./Timeline.module.css";
6
6
  const TimelineItem = (props) => {