reshaped 2.10.6 → 2.10.8
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.
- package/CHANGELOG.md +11 -1
- package/bundle.css +1 -1
- package/bundle.js +6 -6
- package/components/Actionable/Actionable.js +1 -12
- package/components/DropdownMenu/DropdownMenu.js +4 -6
- package/components/Slider/Slider.module.css +1 -1
- package/components/Slider/Slider.types.d.ts +1 -0
- package/components/Slider/Slider.utilities.d.ts +2 -0
- package/components/Slider/Slider.utilities.js +14 -0
- package/components/Slider/SliderControlled.js +2 -4
- package/components/Slider/SliderThumb.js +5 -3
- package/components/Slider/tests/Slider.stories.d.ts +1 -0
- package/components/Slider/tests/Slider.stories.js +5 -0
- package/hooks/_private/useSingletonHotkeys.js +3 -1
- package/hooks/tests/useHotkeys.stories.d.ts +1 -2
- package/hooks/tests/useHotkeys.stories.js +0 -1
- package/hooks/useHotkeys.d.ts +1 -0
- package/hooks/useHotkeys.js +3 -1
- package/package.json +1 -1
@@ -1,13 +1,12 @@
|
|
1
1
|
"use client";
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
3
|
-
import
|
3
|
+
import { forwardRef } from "react";
|
4
4
|
import { classNames } from "../../utilities/helpers.js";
|
5
5
|
import s from "./Actionable.module.css";
|
6
6
|
const Actionable = forwardRef((props, ref) => {
|
7
7
|
const { children, href, onClick, type, disabled, insetFocus, borderRadius, as, fullWidth, className, attributes, } = props;
|
8
8
|
const rootClassNames = classNames(s.root, className, disabled && s["--disabled"], borderRadius && s[`--radius-${borderRadius}`], insetFocus && s["--inset"], fullWidth && s["--full-width"]);
|
9
9
|
const rootAttributes = Object.assign({}, attributes);
|
10
|
-
const repeatRef = React.useRef(false);
|
11
10
|
const hasClickHandler = onClick || (attributes === null || attributes === void 0 ? void 0 : attributes.onClick);
|
12
11
|
const hasFocusHandler = (attributes === null || attributes === void 0 ? void 0 : attributes.onFocus) || (attributes === null || attributes === void 0 ? void 0 : attributes.onBlur);
|
13
12
|
const isLink = Boolean(href || (attributes === null || attributes === void 0 ? void 0 : attributes.href));
|
@@ -36,12 +35,6 @@ const Actionable = forwardRef((props, ref) => {
|
|
36
35
|
var _a;
|
37
36
|
if (disabled)
|
38
37
|
return;
|
39
|
-
/**
|
40
|
-
* - Holding enter keep onClick getting triggered
|
41
|
-
* - Storybook environment is triggering onClick twice on each enter press
|
42
|
-
*/
|
43
|
-
if (repeatRef.current)
|
44
|
-
return;
|
45
38
|
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
46
39
|
(_a = attributes === null || attributes === void 0 ? void 0 : attributes.onClick) === null || _a === void 0 ? void 0 : _a.call(attributes, event);
|
47
40
|
};
|
@@ -56,10 +49,6 @@ const Actionable = forwardRef((props, ref) => {
|
|
56
49
|
return;
|
57
50
|
event.preventDefault();
|
58
51
|
handlePress(event);
|
59
|
-
repeatRef.current = true;
|
60
|
-
requestAnimationFrame(() => {
|
61
|
-
repeatRef.current = false;
|
62
|
-
});
|
63
52
|
};
|
64
53
|
return (_jsx(TagName, Object.assign({ ref: ref }, rootAttributes, { className: rootClassNames, onClick: handlePress, onKeyDown: handleKeyDown, children: children })));
|
65
54
|
});
|
@@ -19,7 +19,6 @@ import { useFlyoutContext } from "../_private/Flyout/index.js";
|
|
19
19
|
import IconChevronRight from "../../icons/ChevronRight.js";
|
20
20
|
import useHotkeys from "../../hooks/useHotkeys.js";
|
21
21
|
import useRTL from "../../hooks/useRTL.js";
|
22
|
-
import { getActiveElement } from "../../utilities/a11y.js";
|
23
22
|
import { classNames } from "../../utilities/helpers.js";
|
24
23
|
import * as keys from "../../constants/keys.js";
|
25
24
|
import s from "./DropdownMenu.module.css";
|
@@ -30,6 +29,7 @@ const DropdownMenu = (props) => {
|
|
30
29
|
};
|
31
30
|
const DropdownMenuContent = (props) => {
|
32
31
|
const { children, attributes, className } = props;
|
32
|
+
const { flyout } = useFlyoutContext();
|
33
33
|
const subMenuInstance = React.useContext(DropdownMenuSubContext);
|
34
34
|
const [rtl] = useRTL();
|
35
35
|
const { ref } = useHotkeys({
|
@@ -37,11 +37,9 @@ const DropdownMenuContent = (props) => {
|
|
37
37
|
var _a;
|
38
38
|
(_a = subMenuInstance === null || subMenuInstance === void 0 ? void 0 : subMenuInstance.current) === null || _a === void 0 ? void 0 : _a.close();
|
39
39
|
},
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
},
|
44
|
-
}, [subMenuInstance === null || subMenuInstance === void 0 ? void 0 : subMenuInstance.current]);
|
40
|
+
}, [subMenuInstance === null || subMenuInstance === void 0 ? void 0 : subMenuInstance.current], {
|
41
|
+
disabled: flyout.status === "idle",
|
42
|
+
});
|
45
43
|
const contentClassName = classNames(s.menu, className);
|
46
44
|
return (_jsx(Popover.Content, { className: contentClassName, attributes: Object.assign(Object.assign({}, attributes), { ref }), children: children }));
|
47
45
|
};
|
@@ -1 +1 @@
|
|
1
|
-
.root{align-items:center;cursor:pointer;display:flex;height:var(--rs-unit-x4);user-select:none;-webkit-tap-highlight-color:transparent}.bar,.root{position:relative}.bar{background:var(--rs-color-background-neutral);border-radius:var(--rs-unit-radius-small);height:var(--rs-unit-x1);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-unit-radius-small);bottom:100%;box-shadow:var(--rs-shadow-overlay);box-sizing:initial;color:var(--rs-color-foreground-neutral);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;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}.thumb,.tooltip{position:absolute}.thumb{height:100%;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-unit-x4);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:box-shadow;width:var(--rs-unit-x4)}.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))}.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))!important}.--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{align-items:center;cursor:pointer;display:flex;height:var(--rs-unit-x4);user-select:none;-webkit-tap-highlight-color:transparent}.bar,.root{position:relative}.bar{background:var(--rs-color-background-neutral);border-radius:var(--rs-unit-radius-small);height:var(--rs-unit-x1);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-unit-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;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}.thumb,.tooltip{position:absolute}.thumb{height:100%;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-unit-x4);transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:box-shadow;width:var(--rs-unit-x4)}.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}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
export const getPrecision = (value) => {
|
2
|
+
const floatPart = value.toString().split(".")[1];
|
3
|
+
return (floatPart === null || floatPart === void 0 ? void 0 : floatPart.length) || 0;
|
4
|
+
};
|
5
|
+
export const applyStepToValue = (value, step) => {
|
6
|
+
const isStepFloat = step % 1 !== 0;
|
7
|
+
const result = Math.round(value / step) * step;
|
8
|
+
// Handle javascript floats manually with string conversion
|
9
|
+
if (isStepFloat) {
|
10
|
+
const precision = getPrecision(step);
|
11
|
+
return Number(result.toFixed(precision));
|
12
|
+
}
|
13
|
+
return result;
|
14
|
+
};
|
@@ -7,15 +7,13 @@ 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
11
|
import s from "./Slider.module.css";
|
11
12
|
const getDragX = (event) => {
|
12
13
|
if (event instanceof MouseEvent)
|
13
14
|
return event.pageX || event.screenX;
|
14
15
|
return event.changedTouches[0].pageX;
|
15
16
|
};
|
16
|
-
const applyStepToValue = (value, step) => {
|
17
|
-
return Math.round(value / step) * step;
|
18
|
-
};
|
19
17
|
const SliderControlled = (props) => {
|
20
18
|
var _a;
|
21
19
|
const { name, range, max, min, step = 1, onChange, onChangeCommit, renderValue, className, attributes, } = props;
|
@@ -200,6 +198,6 @@ const SliderControlled = (props) => {
|
|
200
198
|
_jsxs("div", Object.assign({}, attributes, { className: rootClassNames, onMouseDown: handleMouseDown, onTouchStart: handleMouseDown, children: [_jsx("div", { className: s.bar, ref: barRef, children: _jsx("div", { className: s.selection, style: {
|
201
199
|
insetInlineStart: `${minPercentPosition || 0}%`,
|
202
200
|
width: `${maxPercentPosition - (minPercentPosition || 0)}%`,
|
203
|
-
} }) }), 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 })), _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 })] })));
|
201
|
+
} }) }), 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 })] })));
|
204
202
|
};
|
205
203
|
export default SliderControlled;
|
@@ -4,15 +4,17 @@ import React from "react";
|
|
4
4
|
import { classNames } from "../../utilities/helpers.js";
|
5
5
|
import Theme from "../Theme/index.js";
|
6
6
|
import Text from "../Text/index.js";
|
7
|
+
import { getPrecision } from "./Slider.utilities.js";
|
7
8
|
import s from "./Slider.module.css";
|
8
9
|
const SliderThumb = (props, ref) => {
|
9
|
-
const { name, value, disabled, active, position, max, min, onChange, onDragStart, renderValue, tooltipRef, } = props;
|
10
|
+
const { name, value, disabled, active, position, max, min, step, onChange, onDragStart, renderValue, tooltipRef, } = props;
|
10
11
|
const id = React.useId();
|
11
12
|
const thumbClassNames = classNames(s.thumb, active && s["thumb--active"]);
|
12
|
-
const
|
13
|
+
const precision = getPrecision(step);
|
14
|
+
const tooltipValue = renderValue ? renderValue({ value }) : value.toFixed(precision);
|
13
15
|
const handleChange = (e) => {
|
14
16
|
onChange(+e.target.value);
|
15
17
|
};
|
16
|
-
return (_jsxs(_Fragment, { children: [_jsx("input", { className: s.input, type: "range", name: name, value: value, onChange: handleChange, disabled: disabled, max: max, min: min, "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 }), _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 }) }) })] }));
|
17
19
|
};
|
18
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 step: () => import("react").JSX.Element;
|
12
13
|
export declare const boundaries: () => import("react").JSX.Element;
|
13
14
|
export declare const status: () => import("react").JSX.Element;
|
14
15
|
export declare const customRender: () => import("react").JSX.Element;
|
@@ -18,6 +18,11 @@ export const base = () => (<Example>
|
|
18
18
|
<Slider range name="slider" defaultMinValue={30} defaultMaxValue={70} renderValue={() => "Hundred more times"}/>
|
19
19
|
</Example.Item>
|
20
20
|
</Example>);
|
21
|
+
export const step = () => (<Example>
|
22
|
+
<Example.Item title="float step">
|
23
|
+
<Slider name="slider" defaultValue={30} step={0.01}/>
|
24
|
+
</Example.Item>
|
25
|
+
</Example>);
|
21
26
|
export const boundaries = () => (<Example>
|
22
27
|
<Example.Item title="min: 20, max: 30, value: 25">
|
23
28
|
<Slider name="slider" defaultValue={25} min={20} max={30}/>
|
@@ -98,7 +98,9 @@ export class HotkeyStore {
|
|
98
98
|
!(e.target === data.ref.current || data.ref.current.contains(e.target))) {
|
99
99
|
return;
|
100
100
|
}
|
101
|
-
|
101
|
+
const resolvedEvent = pressedMap[pressedId];
|
102
|
+
resolvedEvent === null || resolvedEvent === void 0 ? void 0 : resolvedEvent.preventDefault();
|
103
|
+
data.callback(resolvedEvent);
|
102
104
|
this.hotkeyMap[pressedId].used = true;
|
103
105
|
});
|
104
106
|
}
|
package/hooks/useHotkeys.d.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import React from "react";
|
2
2
|
declare const useHotkeys: <Element_1 extends HTMLElement>(hotkeys: Record<string, ((e: KeyboardEvent) => void) | null>, deps?: unknown[], options?: {
|
3
3
|
ref?: React.RefObject<Element_1> | undefined;
|
4
|
+
disabled?: boolean | undefined;
|
4
5
|
} | undefined) => {
|
5
6
|
ref: React.RefObject<Element_1>;
|
6
7
|
checkHotkeyState: (key: string) => boolean;
|
package/hooks/useHotkeys.js
CHANGED
@@ -6,10 +6,12 @@ const useHotkeys = (hotkeys, deps = [], options) => {
|
|
6
6
|
const generatedRef = React.useRef(null);
|
7
7
|
const elementRef = (options === null || options === void 0 ? void 0 : options.ref) || generatedRef;
|
8
8
|
React.useEffect(() => {
|
9
|
+
if (options === null || options === void 0 ? void 0 : options.disabled)
|
10
|
+
return;
|
9
11
|
const remove = addHotkeys(hotkeys, elementRef);
|
10
12
|
return () => remove === null || remove === void 0 ? void 0 : remove();
|
11
13
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
12
|
-
}, [addHotkeys, Object.keys(hotkeys).join(","), ...deps]);
|
14
|
+
}, [addHotkeys, Object.keys(hotkeys).join(","), options === null || options === void 0 ? void 0 : options.disabled, ...deps]);
|
13
15
|
return { ref: elementRef, checkHotkeyState: isPressed };
|
14
16
|
};
|
15
17
|
export default useHotkeys;
|
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": "2.10.
|
4
|
+
"version": "2.10.8",
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
6
6
|
"email": "hello@reshaped.so",
|
7
7
|
"homepage": "https://reshaped.so",
|