reshaped 3.0.1 → 3.0.3

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.
@@ -39,13 +39,14 @@ const ModalSubtitle = (props) => {
39
39
  return (_jsx(Text, { variant: "body-3", color: "neutral-faded", attributes: { id: `${id}-subtitle` }, children: children }));
40
40
  };
41
41
  const Modal = (props) => {
42
- const { children, onClose, onOpen, active, size, padding = 4, position = "center", transparentOverlay, ariaLabel, autoFocus = true, overlayClassName, className, attributes, } = props;
42
+ const { children, onClose, onOpen, active, size, padding = 4, position = "center", transparentOverlay, ariaLabel, autoFocus = true, disableSwipeGesture, overlayClassName, className, attributes, } = props;
43
43
  const id = useElementId();
44
44
  const clientPosition = useResponsiveClientValue(position);
45
45
  const [titleMounted, setTitleMounted] = React.useState(false);
46
46
  const [subtitleMounted, setSubtitleMounted] = React.useState(false);
47
47
  const [dragging, setDragging] = React.useState(false);
48
- const rootRef = React.useRef(null);
48
+ const internalRootRef = React.useRef(null);
49
+ const rootRef = attributes?.ref || internalRootRef;
49
50
  const dragStartCoordinatesRef = React.useRef({ x: 0, y: 0 });
50
51
  const dragLastCoordinateRef = React.useRef(0);
51
52
  const dragDistanceRef = React.useRef(0);
@@ -67,6 +68,8 @@ const Modal = (props) => {
67
68
  setDragDistance(0);
68
69
  };
69
70
  const handleDragStart = (e) => {
71
+ if (disableSwipeGesture)
72
+ return;
70
73
  let currentEl = e.target;
71
74
  const rootEl = rootRef.current;
72
75
  while (currentEl && (currentEl === rootEl || rootEl?.contains(currentEl))) {
@@ -155,7 +158,7 @@ const Modal = (props) => {
155
158
  const progress = Math.abs(dragDistance) / size;
156
159
  setHideProgress(progress / 2);
157
160
  dragDistanceRef.current = dragDistance;
158
- }, [dragDistance, clientPosition]);
161
+ }, [dragDistance, clientPosition, rootRef]);
159
162
  return (_jsx(Overlay, { onClose: onClose, onOpen: onOpen, active: active, transparent: transparentOverlay || hideProgress, className: overlayClassName, attributes: {
160
163
  onTouchStart: handleDragStart,
161
164
  }, children: ({ active }) => {
@@ -20,11 +20,14 @@ export type Props = {
20
20
  padding?: G.Responsive<number>;
21
21
  active?: boolean;
22
22
  transparentOverlay?: boolean;
23
+ disableSwipeGesture?: boolean;
23
24
  autoFocus?: boolean;
24
25
  onClose?: () => void;
25
26
  onOpen?: () => void;
26
27
  ariaLabel?: string;
27
28
  className?: G.ClassName;
28
29
  overlayClassName?: G.ClassName;
29
- attributes?: G.Attributes<"div">;
30
+ attributes?: G.Attributes<"div"> & {
31
+ ref?: React.RefObject<HTMLDivElement | null>;
32
+ };
30
33
  };
@@ -166,6 +166,10 @@ export const edgeCases = () => {
166
166
  </Modal>
167
167
  </Example.Item>
168
168
 
169
+ <Example.Item title="disableSwipeGesture">
170
+ <Demo disableSwipeGesture position="start"/>
171
+ </Example.Item>
172
+
169
173
  <Example.Item title="scroll locks on open">
170
174
  <Demo />
171
175
  <View height="1000px"/>
@@ -1 +1 @@
1
- :root{--rs-z-index-raised:5;--rs-z-index-flyout:80;--rs-z-index-fixed:90;--rs-z-index-overlay:100;--rs-z-index-notification:110}blockquote,body,dd,dl,figcaption,figure,h1,h2,h3,h4,h5,h6,li,ol,p,ul{margin:0;padding:0}ol[class],ul[class]{list-style:none}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}fieldset{border:0;margin:0;padding:0}img{display:block;max-width:100%}button,input,select,textarea{font:inherit}option{background:var(--rs-color-background-elevation-base)}label{cursor:pointer}input::placeholder,textarea::placeholder{color:var(--rs-color-foreground-neutral-faded);opacity:.5}html{-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;font-family:var(--rs-font-family-body);font-size:87.5%;font-weight:var(--rs-font-weight-regular);line-height:var(--rs-line-height-body-3);text-rendering:optimizelegibility;touch-action:manipulation}*{box-sizing:border-box}body,html{background:var(--rs-color-background-page);color:var(--rs-color-foreground-neutral);height:100%;scroll-behavior:smooth}[data-rs-theme]:not(html){font-family:var(--rs-font-family-body);font-size:var(--rs-font-size-body-3);font-weight:var(--rs-font-weight-regular);line-height:var(--rs-line-height-body-3)}[data-rs-color-mode=light]{color-scheme:light}[data-rs-color-mode=dark]{color-scheme:dark}@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:.01ms!important}}[data-rs-no-transition] *,[data-rs-no-transition] :after,[data-rs-no-transition] :before{transition:none!important}
1
+ :root{--rs-z-index-raised:5;--rs-z-index-flyout:80;--rs-z-index-fixed:90;--rs-z-index-overlay:100;--rs-z-index-notification:110}@layer rs.reset{blockquote,body,dd,dl,figcaption,figure,h1,h2,h3,h4,h5,h6,li,ol,p,ul{margin:0;padding:0}ol[class],ul[class]{list-style:none}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}fieldset{border:0;margin:0;padding:0}img{display:block;max-width:100%}button,input,select,textarea{font:inherit}option{background:var(--rs-color-background-elevation-base)}label{cursor:pointer}input::placeholder,textarea::placeholder{color:var(--rs-color-foreground-neutral-faded);opacity:.5}html{-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;font-family:var(--rs-font-family-body);font-size:87.5%;font-weight:var(--rs-font-weight-regular);line-height:var(--rs-line-height-body-3);text-rendering:optimizelegibility;touch-action:manipulation}*{box-sizing:border-box}body,html{background:var(--rs-color-background-page);color:var(--rs-color-foreground-neutral);height:100%;scroll-behavior:smooth}}[data-rs-theme]:not(html){font-family:var(--rs-font-family-body);font-size:var(--rs-font-size-body-3);font-weight:var(--rs-font-weight-regular);line-height:var(--rs-line-height-body-3)}[data-rs-color-mode=light]{color-scheme:light}[data-rs-color-mode=dark]{color-scheme:dark}@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:.01ms!important}}[data-rs-no-transition] *,[data-rs-no-transition] :after,[data-rs-no-transition] :before{transition:none!important}
@@ -1 +1 @@
1
- .root{--rs-slider-overflow-gap:var(--rs-unit-x1);--rs-slider-thumb-size:var(--rs-unit-x4);align-items:center;cursor:pointer;display:flex;height:var(--rs-slider-thumb-size);position:relative;user-select:none;-webkit-tap-highlight-color:transparent;margin-inline:calc(var(--rs-slider-overflow-gap) * -1);overflow-x:clip;padding-inline:var(--rs-slider-overflow-gap)}.root:has(.thumb:hover,.thumb--active,.input:focus){overflow:visible}.bar{background:var(--rs-color-background-neutral);border-radius:var(--rs-radius-small);height:var(--rs-unit-x1);position:relative;width:100%}.bar,.input{overflow:hidden}.input{height:1px;opacity:0;pointer-events:none;position:absolute;width:1px}.selection{background:var(--rs-color-background-primary);height:100%;position:absolute}.tooltip{--rs-slider-tooltip-translate-x:calc(-50% + var(--rs-slider-tooltip-offset, 0px));background:var(--rs-color-background-elevation-overlay);border-radius:var(--rs-radius-small);bottom:100%;box-shadow:var(--rs-shadow-overlay);box-sizing:initial;color:var(--rs-color-foreground-neutral);font-variant-numeric:tabular-nums;left:50%;min-width:var(--rs-line-height-caption-1);opacity:0;padding:calc(var(--rs-unit-x1) / 2) var(--rs-unit-x1);pointer-events:none;position:absolute;text-align:center;transform:translate(var(--rs-slider-tooltip-translate-x));transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:opacity,transform;user-select:none;white-space:nowrap;will-change:transform}.thumbs{inset-inline:calc(var(--rs-slider-thumb-size) / 2 + var(--rs-slider-overflow-gap))}.thumb,.thumbs{height:100%;position:absolute}.thumb{width:0}.thumb:before{background:var(--rs-color-background-primary);border-radius:999px;box-shadow:0 0 0 2px var(--rs-color-background-elevation-base);box-sizing:border-box;height:var(--rs-slider-thumb-size);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:box-shadow;width:var(--rs-slider-thumb-size)}.thumb:after,.thumb:before{content:"";left:0;position:absolute;top:50%;transform:translate(-50%,-50%)}.thumb:after{cursor:grab;height:var(--rs-unit-x7);width:var(--rs-unit-x7)}.thumb:hover .tooltip{opacity:1;transform:translate(var(--rs-slider-tooltip-translate-x),calc(var(--rs-unit-x1) * -1.5))}.input:focus+.thumb:after,.thumb--active:after{cursor:grabbing}.input:focus+.thumb:before,.thumb--active:before{box-shadow:0 0 0 1px var(--rs-color-background-elevation-base)}.input:focus+.thumb .tooltip,.thumb--active .tooltip{opacity:1;transform:translate(var(--rs-slider-tooltip-translate-x),calc(var(--rs-unit-x1) * -1.5))!important}.input:focus+.thumb:before{box-shadow:var(--rs-focus-shadow)}.--disabled{cursor:not-allowed}.--disabled .bar{background-color:var(--rs-color-background-disabled)}.--disabled .selection,.--disabled .thumb:before{background-color:var(--rs-color-foreground-disabled)}.--disabled .thumb:after{cursor:not-allowed}.--disabled .thumb:hover .tooltip{opacity:0}
1
+ .root{--rs-slider-overflow-gap:var(--rs-unit-x1);--rs-slider-thumb-size:var(--rs-unit-x4);align-items:center;cursor:pointer;display:flex;position:relative;user-select:none;-webkit-tap-highlight-color:transparent}.root:has(.thumb:hover,.thumb--active,.input:focus){overflow:visible}.bar{background:var(--rs-color-background-neutral);border-radius:var(--rs-radius-small);position:relative}.bar,.input{overflow:hidden}.input{height:1px;opacity:0;pointer-events:none;position:absolute;width:1px}.selection{background:var(--rs-color-background-primary);position:absolute}.tooltip{--rs-slider-tooltip-translate:calc(-50% + var(--rs-slider-tooltip-offset, 0px));background:var(--rs-color-background-elevation-overlay);border-radius:var(--rs-radius-small);box-shadow:var(--rs-shadow-overlay);box-sizing:initial;color:var(--rs-color-foreground-neutral);font-variant-numeric:tabular-nums;min-width:var(--rs-line-height-caption-1);opacity:0;padding:calc(var(--rs-unit-x1) / 2) var(--rs-unit-x1);pointer-events:none;text-align:center;transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:opacity,transform;user-select:none;white-space:nowrap;will-change:transform}.thumb,.thumbs,.tooltip{position:absolute}.thumb:before{background:var(--rs-color-background-primary);border-radius:999px;box-shadow:0 0 0 2px var(--rs-color-background-elevation-base);box-sizing:border-box;height:var(--rs-slider-thumb-size);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:box-shadow;width:var(--rs-slider-thumb-size)}.thumb:after,.thumb:before{content:"";position:absolute}.thumb:after{cursor:grab;height:var(--rs-unit-x7);width:var(--rs-unit-x7)}.thumb:hover .tooltip{opacity:1}.input:focus+.thumb:after,.thumb--active:after{cursor:grabbing}.input:focus+.thumb:before,.thumb--active:before{box-shadow:0 0 0 1px var(--rs-color-background-elevation-base)}.input:focus+.thumb .tooltip,.thumb--active .tooltip{opacity:1}.input:focus+.thumb:before{box-shadow:var(--rs-focus-shadow)}.--orientation-horizontal{height:var(--rs-slider-thumb-size);margin-inline:calc(var(--rs-slider-overflow-gap) * -1);overflow-x:clip;padding-inline:var(--rs-slider-overflow-gap)}.--orientation-horizontal .bar{height:var(--rs-unit-x1);width:100%}.--orientation-horizontal .selection{height:100%;inset-inline-start:var(--rs-slider-selection-start);width:var(--rs-slider-selection-size)}.--orientation-horizontal .tooltip{bottom:100%;left:50%;transform:translate(var(--rs-slider-tooltip-translate))}.--orientation-horizontal .thumbs{height:100%;inset-inline:calc(var(--rs-slider-thumb-size) / 2 + var(--rs-slider-overflow-gap))}.--orientation-horizontal .thumb{height:100%;inset-inline-start:var(--ts-slider-thumb-position);width:0}.--orientation-horizontal .thumb:after,.--orientation-horizontal .thumb:before{left:0;top:50%;transform:translate(-50%,-50%)}.--orientation-horizontal .input:focus+.thumb .tooltip,.--orientation-horizontal .thumb--active .tooltip,.--orientation-horizontal .thumb:hover .tooltip{transform:translate(var(--rs-slider-tooltip-translate),calc(var(--rs-unit-x1) * -1.5))}.--orientation-vertical{flex-direction:column;height:100%;margin-block:calc(var(--rs-slider-overflow-gap) * -1);overflow-y:clip;padding-block:var(--rs-slider-overflow-gap);width:var(--rs-slider-thumb-size)}.--orientation-vertical .bar{height:100%;width:var(--rs-unit-x1)}.--orientation-vertical .selection{height:var(--rs-slider-selection-size);inset-block-end:var(--rs-slider-selection-start);inset-inline-start:auto;width:100%}.--orientation-vertical .tooltip{inset-inline-start:100%;top:50%;transform:translateY(var(--rs-slider-tooltip-translate))}.--orientation-vertical .thumbs{inset-block:calc(var(--rs-slider-thumb-size) / 2 + var(--rs-slider-overflow-gap));width:100%}.--orientation-vertical .thumb{height:0;inset-block-end:var(--ts-slider-thumb-position);width:100%}.--orientation-vertical .thumb:after,.--orientation-vertical .thumb:before{left:50%;top:0;transform:translate(-50%,-50%)}.--orientation-vertical .input:focus+.thumb .tooltip,.--orientation-vertical .thumb--active .tooltip,.--orientation-vertical .thumb:hover .tooltip{transform:translate(calc(var(--rs-unit-x1) * 1.5),-50%)}.--disabled{cursor:not-allowed}.--disabled .bar{background-color:var(--rs-color-background-disabled)}.--disabled .selection,.--disabled .thumb:before{background-color:var(--rs-color-foreground-disabled)}.--disabled .thumb:after{cursor:not-allowed}.--disabled .thumb:hover .tooltip{opacity:0}
@@ -47,6 +47,7 @@ type BaseProps = {
47
47
  disabled?: boolean;
48
48
  min?: number;
49
49
  max?: number;
50
+ orientation?: "vertical" | "horizontal";
50
51
  renderValue?: (args: {
51
52
  value: number;
52
53
  }) => string;
@@ -74,6 +75,7 @@ export type ThumbProps = {
74
75
  max: number;
75
76
  min: number;
76
77
  step: NonNullable<BaseProps["step"]>;
78
+ orientation: NonNullable<BaseProps["orientation"]>;
77
79
  renderValue?: BaseProps["renderValue"];
78
80
  tooltipRef: React.RefObject<HTMLDivElement>;
79
81
  };
@@ -1,2 +1,6 @@
1
1
  export declare const getPrecision: (value: number) => number;
2
2
  export declare const applyStepToValue: (value: number, step: number) => number;
3
+ export declare const getDragCoord: ({ event, vertical, }: {
4
+ event: MouseEvent | TouchEvent;
5
+ vertical?: boolean;
6
+ }) => number;
@@ -12,3 +12,13 @@ export const applyStepToValue = (value, step) => {
12
12
  }
13
13
  return result;
14
14
  };
15
+ export const getDragCoord = ({ event, vertical, }) => {
16
+ if (vertical) {
17
+ if (event instanceof MouseEvent)
18
+ return event.pageY || event.screenY;
19
+ return event.changedTouches[0].pageY;
20
+ }
21
+ if (event instanceof MouseEvent)
22
+ return event.pageX || event.screenX;
23
+ return event.changedTouches[0].pageX;
24
+ };
@@ -2,21 +2,17 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React from "react";
4
4
  import { classNames } from "../../utilities/helpers.js";
5
- import { enableUserSelect, disableUserSelect } from "../../utilities/dom.js";
5
+ import { enableUserSelect, disableUserSelect, enableScroll, disableScroll } from "../../utilities/dom.js";
6
6
  import useRTL from "../../hooks/useRTL.js";
7
7
  import useElementId from "../../hooks/useElementId.js";
8
8
  import { useFormControl } from "../FormControl/index.js";
9
9
  import SliderThumb from "./SliderThumb.js";
10
- import { applyStepToValue } from "./Slider.utilities.js";
10
+ import { applyStepToValue, getDragCoord } from "./Slider.utilities.js";
11
11
  import s from "./Slider.module.css";
12
12
  const THUMB_SIZE = 16;
13
- const getDragX = (event) => {
14
- if (event instanceof MouseEvent)
15
- return event.pageX || event.screenX;
16
- return event.changedTouches[0].pageX;
17
- };
18
13
  const SliderControlled = (props) => {
19
- const { name, range, max, min, step = 1, onChange, onChangeCommit, renderValue, className, attributes, } = props;
14
+ const { name, range, max, min, step = 1, onChange, onChangeCommit, renderValue, className, attributes, orientation = "horizontal", } = props;
15
+ const vertical = orientation === "vertical";
20
16
  const minValue = range && props.minValue !== undefined ? applyStepToValue(props.minValue, step) : undefined;
21
17
  const maxValue = applyStepToValue(range ? props.maxValue : props.value, step);
22
18
  const barRef = React.useRef(null);
@@ -32,27 +28,31 @@ const SliderControlled = (props) => {
32
28
  const minId = `${inputId}-min`;
33
29
  const maxId = `${inputId}-max`;
34
30
  const disabled = formControl?.disabled || props.disabled;
35
- const rootClassNames = classNames(s.root, disabled && s["--disabled"], className);
36
- const getPositionValue = React.useCallback((x) => {
37
- if (!barRef.current)
31
+ const rootClassNames = classNames(s.root, disabled && s["--disabled"], orientation && s[`--orientation-${orientation}`], className);
32
+ const getPositionValue = React.useCallback((dragCoord) => {
33
+ const barEl = barRef.current;
34
+ if (!barEl)
38
35
  return;
39
- const barWidth = barRef.current.clientWidth;
36
+ const barSize = vertical ? barEl.clientHeight : barEl.clientWidth;
37
+ const barRect = barEl.getBoundingClientRect();
40
38
  // Move by half thumb size since it's a reserved space
41
- const barX = barRef.current.getBoundingClientRect().left + THUMB_SIZE / 2;
42
- const positionX = x - barX;
43
- const thumbsAreaWidth = barWidth - THUMB_SIZE;
44
- let percentage = positionX / thumbsAreaWidth;
45
- if (rtl)
39
+ const barCoord = barRect[vertical ? "top" : "left"] + THUMB_SIZE / 2;
40
+ const position = dragCoord - barCoord;
41
+ const thumbsAreaWidth = barSize - THUMB_SIZE;
42
+ let percentage = position / thumbsAreaWidth;
43
+ if (rtl || vertical)
46
44
  percentage = 1 - percentage;
47
45
  let value = (max - min) * percentage + min;
48
46
  value = Math.max(min, Math.min(max, value));
49
47
  return applyStepToValue(value, step);
50
- }, [max, min, rtl, step]);
48
+ }, [max, min, rtl, step, vertical]);
51
49
  const getPercentPosition = (value) => {
52
50
  const ratio = (value - min) / (max - min);
53
51
  return ratio * 100;
54
52
  };
55
53
  const positionTooltip = React.useCallback((draggingId) => {
54
+ if (vertical)
55
+ return;
56
56
  const draggingRef = draggingId === minId ? minTooltipRef : maxTooltipRef;
57
57
  const thumbRef = draggingId === minId ? minRef : maxRef;
58
58
  let nextTooltipOffset = 0;
@@ -75,7 +75,7 @@ const SliderControlled = (props) => {
75
75
  if (tooltipEl) {
76
76
  tooltipEl.style.setProperty("--rs-slider-tooltip-offset", `${nextTooltipOffset || 0}px`);
77
77
  }
78
- }, [minId]);
78
+ }, [minId, vertical]);
79
79
  const handleMinChange = React.useCallback((value, options) => {
80
80
  if (!range)
81
81
  return;
@@ -100,8 +100,8 @@ const SliderControlled = (props) => {
100
100
  return;
101
101
  let minDistance;
102
102
  let closestId;
103
- const x = getDragX(nativeEvent);
104
- const nextValue = getPositionValue(x);
103
+ const dragCoord = getDragCoord({ event: nativeEvent, vertical });
104
+ const nextValue = getPositionValue(dragCoord);
105
105
  const thumbs = [
106
106
  { ref: minRef, id: minId },
107
107
  { ref: maxRef, id: maxId },
@@ -110,7 +110,8 @@ const SliderControlled = (props) => {
110
110
  if (!item.ref.current)
111
111
  return;
112
112
  const el = item.ref.current;
113
- const distance = Math.abs(el.getBoundingClientRect().left - x);
113
+ const elRect = el.getBoundingClientRect();
114
+ const distance = Math.abs((vertical ? elRect.top : elRect.left) - dragCoord);
114
115
  if (minDistance === undefined || distance <= minDistance) {
115
116
  minDistance = distance;
116
117
  closestId = item.id;
@@ -123,6 +124,7 @@ const SliderControlled = (props) => {
123
124
  if (closestId === maxId)
124
125
  handleMaxChange(nextValue);
125
126
  disableUserSelect();
127
+ disableScroll();
126
128
  setDraggingId(closestId);
127
129
  };
128
130
  const handleMinDragStart = () => {
@@ -143,13 +145,14 @@ const SliderControlled = (props) => {
143
145
  handleMaxChange(maxValue, { commit: true });
144
146
  }
145
147
  enableUserSelect();
148
+ enableScroll();
146
149
  setDraggingId(null);
147
150
  }, [minValue, maxValue, handleMinChange, handleMaxChange, draggingId, minId, maxId]);
148
151
  const handleDrag = React.useCallback((e) => {
149
152
  if (!draggingId)
150
153
  return;
151
- const x = getDragX(e);
152
- const nextValue = getPositionValue(x);
154
+ const coord = getDragCoord({ event: e, vertical });
155
+ const nextValue = getPositionValue(coord);
153
156
  if (nextValue === undefined)
154
157
  return;
155
158
  // Switch to another id if thumbs overlap
@@ -173,6 +176,7 @@ const SliderControlled = (props) => {
173
176
  handleMinChange,
174
177
  maxId,
175
178
  minId,
179
+ vertical,
176
180
  ]);
177
181
  React.useEffect(() => {
178
182
  positionTooltip(minId);
@@ -196,8 +200,8 @@ const SliderControlled = (props) => {
196
200
  // mouse/touch events only needed for non-keyboard use
197
201
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
198
202
  _jsxs("div", { ...attributes, className: rootClassNames, onMouseDown: handleMouseDown, onTouchStart: handleMouseDown, children: [_jsx("div", { className: s.bar, ref: barRef, children: _jsx("div", { className: s.selection, style: {
199
- insetInlineStart: `${minPercentPosition || 0}%`,
200
- width: `${maxPercentPosition - (minPercentPosition || 0)}%`,
201
- } }) }), _jsxs("div", { className: s.thumbs, children: [minValue !== undefined && minPercentPosition !== undefined && (_jsx(SliderThumb, { id: minId, active: minId === draggingId, name: name, disabled: disabled, onChange: handleMinChange, value: minValue, onDragStart: handleMinDragStart, position: minPercentPosition, max: max, min: min, ref: minRef, tooltipRef: minTooltipRef, renderValue: renderValue, step: step })), _jsx(SliderThumb, { id: maxId, active: maxId === draggingId, name: name, disabled: disabled, onChange: handleMaxChange, value: maxValue, onDragStart: handleMaxDragStart, position: maxPercentPosition, max: max, min: min, ref: maxRef, tooltipRef: maxTooltipRef, renderValue: renderValue, step: step })] })] }));
203
+ "--rs-slider-selection-start": `${minPercentPosition || 0}%`,
204
+ "--rs-slider-selection-size": `${maxPercentPosition - (minPercentPosition || 0)}%`,
205
+ } }) }), _jsxs("div", { className: s.thumbs, children: [minValue !== undefined && minPercentPosition !== undefined && (_jsx(SliderThumb, { id: minId, active: minId === draggingId, name: name, disabled: disabled, onChange: handleMinChange, value: minValue, onDragStart: handleMinDragStart, position: minPercentPosition, max: max, min: min, ref: minRef, tooltipRef: minTooltipRef, renderValue: renderValue, step: step, orientation: orientation })), _jsx(SliderThumb, { id: maxId, active: maxId === draggingId, name: name, disabled: disabled, onChange: handleMaxChange, value: maxValue, onDragStart: handleMaxDragStart, position: maxPercentPosition, max: max, min: min, ref: maxRef, tooltipRef: maxTooltipRef, renderValue: renderValue, step: step, orientation: orientation })] })] }));
202
206
  };
203
207
  export default SliderControlled;
@@ -7,7 +7,7 @@ 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 = (props, ref) => {
10
- const { name, value, disabled, active, position, max, min, step, onChange, onDragStart, renderValue, tooltipRef, } = props;
10
+ const { name, value, disabled, active, position, max, min, step, onChange, onDragStart, renderValue, tooltipRef, 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);
@@ -15,6 +15,6 @@ const SliderThumb = (props, ref) => {
15
15
  const handleChange = (e) => {
16
16
  onChange(+e.target.value);
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 }), _jsx("div", { ref: ref, className: thumbClassNames, onMouseDown: onDragStart, onTouchStart: onDragStart, style: { insetInlineStart: `${position}%` }, id: id, "aria-hidden": "true", children: _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 }), _jsx("div", { ref: ref, className: thumbClassNames, onMouseDown: onDragStart, onTouchStart: onDragStart, style: { "--ts-slider-thumb-position": `${position}%` }, id: id, "aria-hidden": "true", children: _jsx(Theme, { colorMode: "inverted", children: _jsx(Text, { variant: "caption-1", weight: "medium", className: s.tooltip, attributes: { ref: tooltipRef }, children: tooltipValue }) }) })] }));
19
19
  };
20
20
  export default React.forwardRef(SliderThumb);
@@ -9,6 +9,7 @@ declare const _default: {
9
9
  };
10
10
  export default _default;
11
11
  export declare const base: () => import("react").JSX.Element;
12
+ export declare const direction: () => import("react").JSX.Element;
12
13
  export declare const step: () => import("react").JSX.Element;
13
14
  export declare const boundaries: () => import("react").JSX.Element;
14
15
  export declare const status: () => import("react").JSX.Element;
@@ -1,5 +1,6 @@
1
1
  import { Example } from "../../../utilities/storybook/index.js";
2
2
  import Slider from "../index.js";
3
+ import View from "../../View/index.js";
3
4
  import FormControl from "../../FormControl/index.js";
4
5
  export default {
5
6
  title: "Components/Slider",
@@ -14,6 +15,14 @@ export const base = () => (<Example>
14
15
  <Example.Item title="range">
15
16
  <Slider range name="slider" defaultMinValue={30} defaultMaxValue={100} renderValue={() => "Hundred more times"}/>
16
17
  </Example.Item>
18
+ <div style={{ height: 2000 }}/>
19
+ </Example>);
20
+ export const direction = () => (<Example>
21
+ <Example.Item title="vertical">
22
+ <View height="200px">
23
+ <Slider range name="slider" defaultMinValue={30} defaultMaxValue={100} orientation="vertical"/>
24
+ </View>
25
+ </Example.Item>
17
26
  </Example>);
18
27
  export const step = () => (<Example>
19
28
  <Example.Item title="float step">
@@ -1,3 +1,5 @@
1
1
  export declare const getClosestFlyoutTarget: (el: HTMLElement | null) => HTMLElement;
2
2
  export declare const disableUserSelect: () => void;
3
3
  export declare const enableUserSelect: () => void;
4
+ export declare const disableScroll: () => void;
5
+ export declare const enableScroll: () => void;
@@ -16,3 +16,12 @@ export const disableUserSelect = () => {
16
16
  export const enableUserSelect = () => {
17
17
  document.body.style.userSelect = "";
18
18
  };
19
+ const preventDefault = (e) => e.preventDefault();
20
+ export const disableScroll = () => {
21
+ window.addEventListener("wheel", preventDefault, { passive: false });
22
+ window.addEventListener("touchmove", preventDefault, { passive: false });
23
+ };
24
+ export const enableScroll = () => {
25
+ window.removeEventListener("wheel", preventDefault);
26
+ window.removeEventListener("touchmove", preventDefault);
27
+ };
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.0.1",
4
+ "version": "3.0.3",
5
5
  "license": "MIT",
6
6
  "email": "hello@reshaped.so",
7
7
  "homepage": "https://reshaped.so",