react-proportion-slider 0.9.3 → 0.9.5
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/README.md +45 -23
- package/dist/ProportionSlider.d.ts +37 -0
- package/dist/components/DynamicChildPositioner.d.ts +10 -0
- package/dist/components/HiddenSpaceTaker.d.ts +6 -0
- package/dist/components/SliderKnob.d.ts +10 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/types.d.ts +22 -0
- package/dist/index.d.ts +3 -0
- package/dist/react-proportion-slider.es.js +219 -0
- package/dist/react-proportion-slider.es.js.map +1 -0
- package/dist/react-proportion-slider.umd.js +2 -0
- package/dist/react-proportion-slider.umd.js.map +1 -0
- package/dist/utilities/getClientX.d.ts +3 -0
- package/dist/utilities/index.d.ts +3 -0
- package/dist/utilities/isTouchEvent.d.ts +1 -0
- package/dist/utilities/maths.d.ts +1 -0
- package/package.json +3 -7
package/README.md
CHANGED
@@ -1,68 +1,90 @@
|
|
1
1
|
# React Proportion Slider
|
2
2
|
|
3
|
-
> **Note:** This package is currently in beta
|
3
|
+
> **Note:** This package is currently in beta.
|
4
4
|
|
5
5
|
A React component that allows users to adjust the proportion of two elements using a slider.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
9
|
-
(Not yet published to npm)
|
10
|
-
|
11
9
|
```bash
|
12
10
|
npm install react-proportion-slider
|
13
11
|
```
|
14
12
|
|
13
|
+
```bash
|
14
|
+
yarn add react-proportion-slider
|
15
|
+
```
|
16
|
+
|
15
17
|
## Usage
|
16
18
|
|
17
19
|
```tsx
|
18
|
-
import React from "react";
|
19
|
-
import { ProportionSlider } from "react-proportion-slider";
|
20
|
-
|
21
20
|
function App() {
|
22
21
|
const [proportions, setProportions] = React.useState<[number, number]>([
|
23
22
|
50, 50,
|
24
23
|
]);
|
25
24
|
return (
|
26
|
-
<div
|
27
|
-
style={{
|
28
|
-
height: "100%",
|
29
|
-
flex: 1,
|
30
|
-
padding: "20px 200px",
|
31
|
-
display: "flex",
|
32
|
-
flexDirection: "column",
|
33
|
-
justifyContent: "center",
|
34
|
-
}}
|
35
|
-
>
|
25
|
+
<div>
|
36
26
|
<ProportionSlider
|
37
27
|
value={proportions}
|
28
|
+
width={500}
|
38
29
|
proportions={[
|
39
30
|
{
|
40
|
-
|
31
|
+
label: "Skill",
|
41
32
|
backgroundColor: "#31332E",
|
42
33
|
},
|
43
34
|
{
|
44
|
-
|
35
|
+
label: "3.7 Sonnet",
|
45
36
|
backgroundColor: "#5f625C",
|
46
37
|
},
|
47
38
|
]}
|
48
39
|
onChange={(change) => {
|
49
40
|
setProportions(change);
|
50
41
|
}}
|
51
|
-
|
42
|
+
knobOptions={{
|
52
43
|
width: 5,
|
53
44
|
gap: 5,
|
54
45
|
backgroundColor: "#EC1308",
|
55
46
|
}}
|
56
|
-
|
57
|
-
height: 50,
|
58
|
-
displayValueType: "percentage",
|
59
|
-
}}
|
47
|
+
height={50}
|
60
48
|
/>
|
61
49
|
</div>
|
62
50
|
);
|
63
51
|
}
|
64
52
|
```
|
65
53
|
|
54
|
+
## Props
|
55
|
+
|
56
|
+
| Prop Name | Type | Required | Description |
|
57
|
+
| ----------- | ------------------------------------ | -------- | --------------------------------------------------- |
|
58
|
+
| value | [number, number] | Yes | Current values of the two proportions [left, right] |
|
59
|
+
| proportions | [ProportionDetail, ProportionDetail] | Yes | Details for the two proportions [left, right] |
|
60
|
+
| onChange | (values: [number, number]) => void | No | Callback when values change |
|
61
|
+
| knobOptions | SliderKnobOptions | No | Appearance of the slider knob |
|
62
|
+
| height | number | No | Height of the slider in pixels |
|
63
|
+
| width | number | No | Width of the slider in pixels |
|
64
|
+
| disabled | boolean | No | Whether the slider is disabled |
|
65
|
+
| className | string | No | Custom class name for the slider container |
|
66
|
+
| style | React.CSSProperties | No | Custom styles for the slider container |
|
67
|
+
| ariaLabel | string | No | Accessibility label for the slider |
|
68
|
+
|
69
|
+
### ProportionDetail
|
70
|
+
|
71
|
+
| Property | Type | Required | Description |
|
72
|
+
| --------------- | ------ | -------- | ----------------------------------------------- |
|
73
|
+
| label | string | Yes | Custom label to display |
|
74
|
+
| backgroundColor | string | No | Color of the proportion segment |
|
75
|
+
| data | any | No | Optional data to associate with this proportion |
|
76
|
+
| ariaLabel | string | No | Accessibility label for this proportion |
|
77
|
+
|
78
|
+
### SliderKnobOptions
|
79
|
+
|
80
|
+
| Property | Type | Required | Description |
|
81
|
+
| --------------- | ------------------- | -------- | ------------------------------------ |
|
82
|
+
| width | number | No | Width of the slider knob in pixels |
|
83
|
+
| gap | number | No | Gap around the slider knob in pixels |
|
84
|
+
| backgroundColor | string | No | Color of the slider knob |
|
85
|
+
| className | string | No | Custom class name for the knob |
|
86
|
+
| style | React.CSSProperties | No | Custom styles for the knob |
|
87
|
+
|
66
88
|
## Future Features
|
67
89
|
|
68
90
|
1. Make it possible to adjust the proportion of more than two elements
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { CSSProperties } from 'react';
|
2
|
+
import { ProportionDetail, SliderKnobOptions } from './components';
|
3
|
+
export type ProportionSliderProps = {
|
4
|
+
/**
|
5
|
+
* Current values of the two proportions [left, right]
|
6
|
+
* These should be positive numbers
|
7
|
+
*/
|
8
|
+
value: [number, number];
|
9
|
+
/**
|
10
|
+
* Details for the two proportions [left, right]
|
11
|
+
*/
|
12
|
+
proportions: [ProportionDetail, ProportionDetail];
|
13
|
+
/**
|
14
|
+
* Callback when values change
|
15
|
+
* @param values The new values [left, right]
|
16
|
+
*/
|
17
|
+
onChange?: (values: [number, number]) => void;
|
18
|
+
/**
|
19
|
+
* Appearance of the slider knob
|
20
|
+
*/
|
21
|
+
knobOptions?: SliderKnobOptions;
|
22
|
+
/** Height of the slider in pixels */
|
23
|
+
height?: number;
|
24
|
+
/** Width of the slider in pixels */
|
25
|
+
width?: number;
|
26
|
+
/** Whether the slider is disabled */
|
27
|
+
disabled?: boolean;
|
28
|
+
/** Custom class name for the slider container */
|
29
|
+
className?: string;
|
30
|
+
/** Custom styles for the slider container */
|
31
|
+
style?: CSSProperties;
|
32
|
+
/**
|
33
|
+
* Accessibility options
|
34
|
+
*/
|
35
|
+
ariaLabel?: string;
|
36
|
+
};
|
37
|
+
export declare const ProportionSlider: ({ value, proportions, onChange, knobOptions, disabled, height, ariaLabel, className, style, width, }: ProportionSliderProps) => import("react/jsx-runtime").JSX.Element;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { ProportionDetail } from './types';
|
2
|
+
type DynamicChildPositionerProps = {
|
3
|
+
detail: ProportionDetail;
|
4
|
+
primaryNode: "left" | "right";
|
5
|
+
width: number | string;
|
6
|
+
ariaLabel?: string;
|
7
|
+
valueLabel: string;
|
8
|
+
};
|
9
|
+
export declare const DynamicChildPositioner: ({ detail, valueLabel, primaryNode, width, ariaLabel, }: DynamicChildPositionerProps) => import("react/jsx-runtime").JSX.Element;
|
10
|
+
export {};
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { CSSProperties } from 'react';
|
2
|
+
export type SliderKnobProps = {
|
3
|
+
className?: string;
|
4
|
+
width: number;
|
5
|
+
gap: number;
|
6
|
+
backgroundColor?: string;
|
7
|
+
style?: CSSProperties;
|
8
|
+
disabled?: boolean;
|
9
|
+
};
|
10
|
+
export declare const SliderKnob: ({ className, width, gap, backgroundColor, style, disabled, }: SliderKnobProps) => import("react/jsx-runtime").JSX.Element;
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { CSSProperties } from 'react';
|
2
|
+
export type SliderKnobOptions = {
|
3
|
+
/** Width of the slider knob in pixels */
|
4
|
+
width?: number;
|
5
|
+
/** Gap around the slider knob in pixels */
|
6
|
+
gap?: number;
|
7
|
+
/** Color of the slider knob */
|
8
|
+
backgroundColor?: string;
|
9
|
+
/** Custom class name for the knob */
|
10
|
+
className?: string;
|
11
|
+
/** Custom styles for the knob */
|
12
|
+
style?: CSSProperties;
|
13
|
+
};
|
14
|
+
export type ProportionDetail = {
|
15
|
+
/** Custom label to display instead of percentage or value */
|
16
|
+
label: string;
|
17
|
+
/** Color of the proportion segment */
|
18
|
+
backgroundColor?: string;
|
19
|
+
/** Optional data to associate with this proportion */
|
20
|
+
data?: unknown;
|
21
|
+
ariaLabel?: string;
|
22
|
+
};
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
import { jsx as i, jsxs as H } from "react/jsx-runtime";
|
2
|
+
import { useRef as b, useState as N, useMemo as $, useEffect as k, useCallback as W } from "react";
|
3
|
+
const D = ({ children: t }) => /* @__PURE__ */ i("span", { "aria-hidden": "true", style: { visibility: "hidden" }, children: t }), G = ({
|
4
|
+
detail: t,
|
5
|
+
valueLabel: d,
|
6
|
+
primaryNode: e,
|
7
|
+
width: y,
|
8
|
+
ariaLabel: m
|
9
|
+
}) => {
|
10
|
+
const v = /* @__PURE__ */ i("div", { style: Y, children: t.label }), x = /* @__PURE__ */ i("div", { style: Y, children: d }), F = /* @__PURE__ */ i("div", { style: Y, children: "100%" }), I = e === "right" ? v : x, _ = e === "left" ? v : x, p = b(null), a = b(null), s = b(null), [c, M] = N(
|
11
|
+
"both"
|
12
|
+
), C = $(() => {
|
13
|
+
const o = c === "none" || c === "primary" && e === "left";
|
14
|
+
return e === "right" ? o ? w.BOTTOM_RIGHT : w.RIGHT : o ? w.TOP_LEFT : w.RIGHT;
|
15
|
+
}, [c, e]), E = $(() => {
|
16
|
+
const o = c === "none" || c === "primary" && e === "right";
|
17
|
+
return e === "left" ? o ? w.BOTTOM_LEFT : w.LEFT : o ? w.TOP_RIGHT : w.LEFT;
|
18
|
+
}, [c, e]);
|
19
|
+
return k(() => {
|
20
|
+
const o = setInterval(() => {
|
21
|
+
const u = a.current, h = s.current, f = p.current;
|
22
|
+
if (!f || !u || !h)
|
23
|
+
return;
|
24
|
+
const r = f.getBoundingClientRect().width, l = u.getBoundingClientRect().width, n = h.getBoundingClientRect().width, { primaryWidth: T, secondaryWidth: O } = e === "left" ? { primaryWidth: n, secondaryWidth: l } : { primaryWidth: l, secondaryWidth: n }, B = T + 2 * g <= r, S = O + T + 3 * g <= r;
|
25
|
+
M(B ? S ? "both" : "primary" : "none");
|
26
|
+
}, 33.333333333333336);
|
27
|
+
return () => clearInterval(o);
|
28
|
+
}, [p, a, s, e]), /* @__PURE__ */ H(
|
29
|
+
"div",
|
30
|
+
{
|
31
|
+
ref: p,
|
32
|
+
"aria-label": m,
|
33
|
+
style: {
|
34
|
+
position: "relative",
|
35
|
+
width: y,
|
36
|
+
backgroundColor: t.backgroundColor,
|
37
|
+
borderRadius: "5px",
|
38
|
+
color: "white"
|
39
|
+
},
|
40
|
+
children: [
|
41
|
+
/* @__PURE__ */ i("div", { ref: s, style: E, children: _ }),
|
42
|
+
/* @__PURE__ */ i("div", { ref: a, style: C, children: I }),
|
43
|
+
/* @__PURE__ */ i(D, { children: F }),
|
44
|
+
/* @__PURE__ */ i(D, { children: v })
|
45
|
+
]
|
46
|
+
}
|
47
|
+
);
|
48
|
+
}, g = 5, L = {
|
49
|
+
position: "absolute",
|
50
|
+
transition: "all 200ms cubic-bezier(.47,1.64,.41,.8)",
|
51
|
+
transitionProperty: "transform, top, left, bottom, right"
|
52
|
+
}, w = {
|
53
|
+
TOP_LEFT: {
|
54
|
+
...L,
|
55
|
+
left: g,
|
56
|
+
top: -5,
|
57
|
+
transform: "translateY(-100%)"
|
58
|
+
},
|
59
|
+
LEFT: {
|
60
|
+
...L,
|
61
|
+
left: g,
|
62
|
+
top: "50%",
|
63
|
+
transform: "translateY(-50%)"
|
64
|
+
},
|
65
|
+
BOTTOM_LEFT: {
|
66
|
+
...L,
|
67
|
+
left: g,
|
68
|
+
bottom: -5,
|
69
|
+
transform: "translateY(100%)"
|
70
|
+
},
|
71
|
+
TOP_RIGHT: {
|
72
|
+
...L,
|
73
|
+
right: g,
|
74
|
+
top: -5,
|
75
|
+
transform: "translateY(-100%)"
|
76
|
+
},
|
77
|
+
RIGHT: {
|
78
|
+
...L,
|
79
|
+
right: g,
|
80
|
+
top: "50%",
|
81
|
+
transform: "translateY(-50%)"
|
82
|
+
},
|
83
|
+
BOTTOM_RIGHT: {
|
84
|
+
...L,
|
85
|
+
right: g,
|
86
|
+
bottom: -5,
|
87
|
+
transform: "translateY(100%)"
|
88
|
+
}
|
89
|
+
}, Y = {
|
90
|
+
whiteSpace: "nowrap",
|
91
|
+
userSelect: "none"
|
92
|
+
}, K = ({
|
93
|
+
className: t,
|
94
|
+
width: d,
|
95
|
+
gap: e,
|
96
|
+
backgroundColor: y = "red",
|
97
|
+
style: m,
|
98
|
+
disabled: v
|
99
|
+
}) => /* @__PURE__ */ i(
|
100
|
+
"div",
|
101
|
+
{
|
102
|
+
role: "button",
|
103
|
+
className: t,
|
104
|
+
style: {
|
105
|
+
alignSelf: "stretch",
|
106
|
+
borderRadius: "2px",
|
107
|
+
cursor: v ? "not-allowed" : "ew-resize",
|
108
|
+
...m,
|
109
|
+
width: `${d}px`,
|
110
|
+
margin: `${e}px ${e}px`,
|
111
|
+
background: y
|
112
|
+
}
|
113
|
+
}
|
114
|
+
);
|
115
|
+
function X(t) {
|
116
|
+
return "touches" in t;
|
117
|
+
}
|
118
|
+
const j = (t) => X(t) ? t.touches[0].clientX : t.clientX, z = (t, d, e) => Math.min(Math.max(t, d), e), q = ({
|
119
|
+
value: t,
|
120
|
+
proportions: d,
|
121
|
+
onChange: e,
|
122
|
+
knobOptions: y,
|
123
|
+
disabled: m,
|
124
|
+
height: v,
|
125
|
+
ariaLabel: x,
|
126
|
+
className: F,
|
127
|
+
style: I,
|
128
|
+
width: _
|
129
|
+
}) => {
|
130
|
+
const p = A(y), a = b(null), s = t[0] + t[1], c = p.width + p.gap * 2, M = b(s), C = b(c);
|
131
|
+
M.current = s, C.current = c;
|
132
|
+
const E = b(!1), o = W(
|
133
|
+
(r, { width: l, left: n }) => {
|
134
|
+
const T = j(r), O = C.current, B = (T - n - O / 2) / (l - O), S = M.current, P = z(S * B, 0, S);
|
135
|
+
e == null || e([P, S - P]);
|
136
|
+
},
|
137
|
+
[e]
|
138
|
+
), u = W(
|
139
|
+
(r) => {
|
140
|
+
var T;
|
141
|
+
const l = r.target, n = (T = a.current) == null ? void 0 : T.getBoundingClientRect();
|
142
|
+
if (a.current && !a.current.contains(l) || !n || n.width === 0) {
|
143
|
+
console.log("returning because of rect width", n == null ? void 0 : n.width);
|
144
|
+
return;
|
145
|
+
}
|
146
|
+
return r.preventDefault(), E.current = !0, o(r, n), !0;
|
147
|
+
},
|
148
|
+
[o]
|
149
|
+
), h = W(
|
150
|
+
(r) => {
|
151
|
+
var n;
|
152
|
+
const l = (n = a.current) == null ? void 0 : n.getBoundingClientRect();
|
153
|
+
return !E.current || !l || l.width === 0 ? !1 : (r.preventDefault(), o(r, l), !0);
|
154
|
+
},
|
155
|
+
[o]
|
156
|
+
), f = W((r) => E.current ? (E.current = !1, r.preventDefault(), !0) : !1, []);
|
157
|
+
return k(() => (window.addEventListener("mousedown", u), window.addEventListener("mousemove", h), window.addEventListener("mouseup", f), window.addEventListener("touchstart", u), window.addEventListener("touchmove", h), window.addEventListener("touchend", f), () => {
|
158
|
+
window.removeEventListener("mousedown", u), window.removeEventListener("mousemove", h), window.removeEventListener("mouseup", f), window.removeEventListener("touchstart", u), window.removeEventListener("touchmove", h), window.removeEventListener("touchend", f);
|
159
|
+
}), [u, h, f]), /* @__PURE__ */ H(
|
160
|
+
"div",
|
161
|
+
{
|
162
|
+
ref: a,
|
163
|
+
role: "slider",
|
164
|
+
"aria-label": x,
|
165
|
+
"aria-valuenow": Math.round(t[0] / s * 100),
|
166
|
+
style: {
|
167
|
+
display: "flex",
|
168
|
+
flexDirection: "row",
|
169
|
+
height: v,
|
170
|
+
width: _,
|
171
|
+
opacity: m ? 0.6 : 1,
|
172
|
+
cursor: m ? "not-allowed" : "pointer",
|
173
|
+
...I
|
174
|
+
},
|
175
|
+
className: F,
|
176
|
+
children: [
|
177
|
+
/* @__PURE__ */ i(
|
178
|
+
G,
|
179
|
+
{
|
180
|
+
detail: d[0],
|
181
|
+
valueLabel: `${Math.round(t[0] * 100 / s)}%`,
|
182
|
+
width: `calc(${t[0] * 100 / s}% - ${c / 2}px)`,
|
183
|
+
primaryNode: "left"
|
184
|
+
}
|
185
|
+
),
|
186
|
+
/* @__PURE__ */ i(K, { disabled: m, ...p }),
|
187
|
+
/* @__PURE__ */ i(
|
188
|
+
G,
|
189
|
+
{
|
190
|
+
detail: d[1],
|
191
|
+
valueLabel: `${Math.round(t[1] * 100 / s)}%`,
|
192
|
+
width: `calc(${t[1] * 100 / s}% - ${c / 2}px)`,
|
193
|
+
primaryNode: "right"
|
194
|
+
}
|
195
|
+
)
|
196
|
+
]
|
197
|
+
}
|
198
|
+
);
|
199
|
+
}, R = {
|
200
|
+
width: 5,
|
201
|
+
gap: 2,
|
202
|
+
backgroundColor: "red",
|
203
|
+
className: "slider-knob",
|
204
|
+
style: {}
|
205
|
+
};
|
206
|
+
function A(t = {}) {
|
207
|
+
return {
|
208
|
+
width: t.width ?? R.width,
|
209
|
+
gap: t.gap ?? R.gap,
|
210
|
+
backgroundColor: t.backgroundColor ?? R.backgroundColor,
|
211
|
+
className: t.className ?? R.className,
|
212
|
+
style: t.style ?? R.style
|
213
|
+
};
|
214
|
+
}
|
215
|
+
export {
|
216
|
+
q as ProportionSlider,
|
217
|
+
q as default
|
218
|
+
};
|
219
|
+
//# sourceMappingURL=react-proportion-slider.es.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"react-proportion-slider.es.js","sources":["../src/components/HiddenSpaceTaker.tsx","../src/components/DynamicChildPositioner.tsx","../src/components/SliderKnob.tsx","../src/utilities/isTouchEvent.tsx","../src/utilities/getClientX.tsx","../src/utilities/maths.ts","../src/ProportionSlider.tsx"],"sourcesContent":["import React from \"react\";\n\ntype HiddenSpaceTakerProps = {\n children: React.ReactNode;\n};\nexport const HiddenSpaceTaker = ({ children }: HiddenSpaceTakerProps) => (\n <span aria-hidden=\"true\" style={{ visibility: \"hidden\" }}>\n {children}\n </span>\n);\n","import React, { useRef, useState, useMemo, useEffect } from \"react\";\nimport { ProportionDetail } from \"./types\";\nimport { HiddenSpaceTaker } from \"./HiddenSpaceTaker\";\n\ntype DynamicChildPositionerProps = {\n detail: ProportionDetail;\n primaryNode: \"left\" | \"right\";\n width: number | string;\n ariaLabel?: string;\n valueLabel: string;\n};\n\nexport const DynamicChildPositioner = ({\n detail,\n valueLabel,\n primaryNode,\n width,\n ariaLabel,\n}: DynamicChildPositionerProps) => {\n const labelNode = <div style={TEXT_STYLE}>{detail.label}</div>;\n const percentNode = <div style={TEXT_STYLE}>{valueLabel}</div>;\n const maxPercentNode = <div style={TEXT_STYLE}>{`100%`}</div>;\n const rightNode = primaryNode === \"right\" ? labelNode : percentNode;\n const leftNode = primaryNode === \"left\" ? labelNode : percentNode;\n const ref = useRef<HTMLDivElement | null>(null);\n const refRight = useRef<HTMLDivElement | null>(null);\n const refLeft = useRef<HTMLDivElement | null>(null);\n const [fitStatus, setFitStatus] = useState<\"both\" | \"primary\" | \"none\">(\n \"both\"\n );\n\n const rightStyle = useMemo(() => {\n const rightNoSpace =\n fitStatus === \"none\" ||\n (fitStatus === \"primary\" && primaryNode === \"left\");\n if (primaryNode === \"right\") {\n return rightNoSpace ? STYLES[\"BOTTOM_RIGHT\"] : STYLES[\"RIGHT\"];\n } else {\n return rightNoSpace ? STYLES[\"TOP_LEFT\"] : STYLES[\"RIGHT\"];\n }\n }, [fitStatus, primaryNode]);\n\n const leftStyle = useMemo(() => {\n const leftNoSpace =\n fitStatus === \"none\" ||\n (fitStatus === \"primary\" && primaryNode === \"right\");\n if (primaryNode === \"left\") {\n return leftNoSpace ? STYLES[\"BOTTOM_LEFT\"] : STYLES[\"LEFT\"];\n } else {\n return leftNoSpace ? STYLES[\"TOP_RIGHT\"] : STYLES[\"LEFT\"];\n }\n }, [fitStatus, primaryNode]);\n\n useEffect(() => {\n const interval = setInterval(() => {\n const textRight = refRight.current;\n const textLeft = refLeft.current;\n const container = ref.current;\n if (!container || !textRight || !textLeft) {\n return;\n }\n const containerRectWidth = container.getBoundingClientRect().width;\n const rightWidth = textRight.getBoundingClientRect().width;\n const leftWidth = textLeft.getBoundingClientRect().width;\n\n const { primaryWidth, secondaryWidth } =\n primaryNode === \"left\"\n ? { primaryWidth: leftWidth, secondaryWidth: rightWidth }\n : { primaryWidth: rightWidth, secondaryWidth: leftWidth };\n\n const primaryCanFit = primaryWidth + 2 * GAP <= containerRectWidth;\n const secondaryCanFit =\n secondaryWidth + primaryWidth + 3 * GAP <= containerRectWidth;\n\n const fitStatus = primaryCanFit\n ? secondaryCanFit\n ? \"both\"\n : \"primary\"\n : \"none\";\n\n setFitStatus(fitStatus);\n }, 1000 / 30);\n return () => clearInterval(interval);\n }, [ref, refRight, refLeft, primaryNode]);\n\n return (\n <div\n ref={ref}\n aria-label={ariaLabel}\n style={{\n position: \"relative\",\n width,\n backgroundColor: detail.backgroundColor,\n borderRadius: \"5px\",\n color: \"white\",\n }}\n >\n <div ref={refLeft} style={leftStyle}>\n {leftNode}\n </div>\n <div ref={refRight} style={rightStyle}>\n {rightNode}\n </div>\n <HiddenSpaceTaker>{maxPercentNode}</HiddenSpaceTaker>\n <HiddenSpaceTaker>{labelNode}</HiddenSpaceTaker>\n </div>\n );\n};\n\nconst GAP = 5;\nconst COMMON_STYLES: React.CSSProperties = {\n position: \"absolute\",\n transition: \"all 200ms cubic-bezier(.47,1.64,.41,.8)\",\n transitionProperty: \"transform, top, left, bottom, right\",\n};\nconst STYLES: Record<string, React.CSSProperties> = {\n TOP_LEFT: {\n ...COMMON_STYLES,\n left: GAP,\n top: -GAP,\n transform: \"translateY(-100%)\",\n },\n LEFT: {\n ...COMMON_STYLES,\n left: GAP,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n },\n BOTTOM_LEFT: {\n ...COMMON_STYLES,\n left: GAP,\n bottom: -GAP,\n transform: \"translateY(100%)\",\n },\n TOP_RIGHT: {\n ...COMMON_STYLES,\n right: GAP,\n top: -GAP,\n transform: \"translateY(-100%)\",\n },\n RIGHT: {\n ...COMMON_STYLES,\n right: GAP,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n },\n BOTTOM_RIGHT: {\n ...COMMON_STYLES,\n right: GAP,\n bottom: -GAP,\n transform: \"translateY(100%)\",\n },\n};\n\nconst TEXT_STYLE = {\n whiteSpace: \"nowrap\",\n userSelect: \"none\",\n} as const;\n","import { CSSProperties } from \"react\";\n\nexport type SliderKnobProps = {\n className?: string;\n width: number;\n gap: number;\n backgroundColor?: string;\n style?: CSSProperties;\n disabled?: boolean;\n};\n\nexport const SliderKnob = ({\n className,\n width,\n gap,\n backgroundColor = \"red\",\n style,\n disabled,\n}: SliderKnobProps) => {\n return (\n <div\n role=\"button\"\n className={className}\n style={{\n alignSelf: \"stretch\",\n borderRadius: \"2px\",\n cursor: disabled ? \"not-allowed\" : \"ew-resize\",\n ...style,\n width: `${width}px`,\n margin: `${gap}px ${gap}px`,\n background: backgroundColor,\n }}\n ></div>\n );\n};\n","export function isTouchEvent(\n e: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent\n): e is TouchEvent | React.TouchEvent {\n return \"touches\" in e;\n}\n","import React from \"react\";\nimport { isTouchEvent } from \"./isTouchEvent\";\n\nexport type EventType =\n | MouseEvent\n | TouchEvent\n | React.MouseEvent\n | React.TouchEvent;\n\nexport const getClientX = (e: EventType): number => {\n return isTouchEvent(e) ? e.touches[0].clientX : e.clientX;\n};\n","export const clamp = (value: number, min: number, max: number) =>\n Math.min(Math.max(value, min), max);\n","import { useCallback, useRef, CSSProperties, useEffect } from \"react\";\nimport {\n DynamicChildPositioner,\n SliderKnob,\n ProportionDetail,\n SliderKnobOptions,\n} from \"./components\";\nimport { EventType, getClientX, clamp } from \"./utilities\";\n\nexport type ProportionSliderProps = {\n /**\n * Current values of the two proportions [left, right]\n * These should be positive numbers\n */\n value: [number, number];\n\n /**\n * Details for the two proportions [left, right]\n */\n proportions: [ProportionDetail, ProportionDetail];\n\n /**\n * Callback when values change\n * @param values The new values [left, right]\n */\n onChange?: (values: [number, number]) => void;\n\n /**\n * Appearance of the slider knob\n */\n knobOptions?: SliderKnobOptions;\n\n /** Height of the slider in pixels */\n height?: number;\n /** Width of the slider in pixels */\n width?: number;\n /** Whether the slider is disabled */\n disabled?: boolean;\n /** Custom class name for the slider container */\n className?: string;\n /** Custom styles for the slider container */\n style?: CSSProperties;\n\n /**\n * Accessibility options\n */\n ariaLabel?: string;\n};\n\nexport const ProportionSlider = ({\n value,\n proportions,\n onChange,\n knobOptions,\n disabled,\n height,\n ariaLabel,\n className,\n style,\n width,\n}: ProportionSliderProps) => {\n const mergedKnobOptions = getMergeKnobOptions(knobOptions);\n\n const ref = useRef<HTMLDivElement | null>(null);\n const total = value[0] + value[1];\n const sliderWidth = mergedKnobOptions.width + mergedKnobOptions.gap * 2;\n const refTotal = useRef<number>(total);\n const refSliderWidth = useRef<number>(sliderWidth);\n refTotal.current = total;\n refSliderWidth.current = sliderWidth;\n const refIsDragging = useRef<boolean>(false);\n\n const onChangeValueFromEvent = useCallback(\n (e: EventType, { width, left }: { width: number; left: number }) => {\n const x = getClientX(e);\n const knobWidth = refSliderWidth.current;\n const factor = (x - left - knobWidth / 2) / (width - knobWidth);\n const total = refTotal.current;\n const value1 = clamp(total * factor, 0, total);\n onChange?.([value1, total - value1]);\n },\n [onChange]\n );\n\n const onDown = useCallback(\n (e: EventType) => {\n const target = e.target as HTMLElement;\n const rect = ref.current?.getBoundingClientRect();\n if (\n (ref.current && !ref.current.contains(target)) ||\n !rect ||\n rect.width === 0\n ) {\n console.log(\"returning because of rect width\", rect?.width);\n return;\n }\n e.preventDefault();\n refIsDragging.current = true;\n onChangeValueFromEvent(e, rect);\n return true;\n },\n [onChangeValueFromEvent]\n );\n\n const onMove = useCallback(\n (e: EventType) => {\n const rect = ref.current?.getBoundingClientRect();\n if (!refIsDragging.current || !rect || rect.width === 0) {\n return false;\n }\n e.preventDefault();\n onChangeValueFromEvent(e, rect);\n return true;\n },\n [onChangeValueFromEvent]\n );\n\n const onUp = useCallback((e: EventType) => {\n if (!refIsDragging.current) return false;\n refIsDragging.current = false;\n e.preventDefault();\n return true;\n }, []);\n\n useEffect(() => {\n window.addEventListener(\"mousedown\", onDown);\n window.addEventListener(\"mousemove\", onMove);\n window.addEventListener(\"mouseup\", onUp);\n window.addEventListener(\"touchstart\", onDown);\n window.addEventListener(\"touchmove\", onMove);\n window.addEventListener(\"touchend\", onUp);\n return () => {\n window.removeEventListener(\"mousedown\", onDown);\n window.removeEventListener(\"mousemove\", onMove);\n window.removeEventListener(\"mouseup\", onUp);\n window.removeEventListener(\"touchstart\", onDown);\n window.removeEventListener(\"touchmove\", onMove);\n window.removeEventListener(\"touchend\", onUp);\n };\n }, [onDown, onMove, onUp]);\n return (\n <div\n ref={ref}\n role=\"slider\"\n aria-label={ariaLabel}\n aria-valuenow={Math.round((value[0] / total) * 100)}\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n height,\n width,\n opacity: disabled ? 0.6 : 1,\n cursor: disabled ? \"not-allowed\" : \"pointer\",\n ...style,\n }}\n className={className}\n >\n <DynamicChildPositioner\n detail={proportions[0]}\n valueLabel={`${Math.round((value[0] * 100) / total)}%`}\n width={`calc(${(value[0] * 100) / total}% - ${sliderWidth / 2}px)`}\n primaryNode=\"left\"\n />\n <SliderKnob disabled={disabled} {...mergedKnobOptions} />\n <DynamicChildPositioner\n detail={proportions[1]}\n valueLabel={`${Math.round((value[1] * 100) / total)}%`}\n width={`calc(${(value[1] * 100) / total}% - ${sliderWidth / 2}px)`}\n primaryNode=\"right\"\n />\n </div>\n );\n};\n\nconst DefaultKnobOptions: Required<SliderKnobOptions> = {\n width: 5,\n gap: 2,\n backgroundColor: \"red\",\n className: \"slider-knob\",\n style: {},\n};\n\nfunction getMergeKnobOptions(\n knobOptions: SliderKnobOptions | undefined = {}\n): Required<SliderKnobOptions> {\n return {\n width: knobOptions.width ?? DefaultKnobOptions.width,\n gap: knobOptions.gap ?? DefaultKnobOptions.gap,\n backgroundColor:\n knobOptions.backgroundColor ?? DefaultKnobOptions.backgroundColor,\n className: knobOptions.className ?? DefaultKnobOptions.className,\n style: knobOptions.style ?? DefaultKnobOptions.style,\n };\n}\n"],"names":["HiddenSpaceTaker","children","jsx","DynamicChildPositioner","detail","valueLabel","primaryNode","width","ariaLabel","labelNode","TEXT_STYLE","percentNode","maxPercentNode","rightNode","leftNode","ref","useRef","refRight","refLeft","fitStatus","setFitStatus","useState","rightStyle","useMemo","rightNoSpace","STYLES","leftStyle","leftNoSpace","useEffect","interval","textRight","textLeft","container","containerRectWidth","rightWidth","leftWidth","primaryWidth","secondaryWidth","primaryCanFit","GAP","secondaryCanFit","jsxs","COMMON_STYLES","SliderKnob","className","gap","backgroundColor","style","disabled","isTouchEvent","e","getClientX","clamp","value","min","max","ProportionSlider","proportions","onChange","knobOptions","height","mergedKnobOptions","getMergeKnobOptions","total","sliderWidth","refTotal","refSliderWidth","refIsDragging","onChangeValueFromEvent","useCallback","left","x","knobWidth","factor","value1","onDown","target","rect","_a","onMove","onUp","DefaultKnobOptions"],"mappings":"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"}
|
@@ -0,0 +1,2 @@
|
|
1
|
+
(function(a,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],n):(a=typeof globalThis<"u"?globalThis:a||self,n(a.ReactProportionSlider={},a.ReactJsxRuntime,a.React))})(this,function(a,n,r){"use strict";const I=({children:t})=>n.jsx("span",{"aria-hidden":"true",style:{visibility:"hidden"},children:t}),B=({detail:t,valueLabel:h,primaryNode:e,width:S,ariaLabel:v})=>{const T=n.jsx("div",{style:G,children:t.label}),P=n.jsx("div",{style:G,children:h}),O=n.jsx("div",{style:G,children:"100%"}),W=e==="right"?T:P,_=e==="left"?T:P,m=r.useRef(null),u=r.useRef(null),c=r.useRef(null),[l,M]=r.useState("both"),C=r.useMemo(()=>{const i=l==="none"||l==="primary"&&e==="left";return e==="right"?i?f.BOTTOM_RIGHT:f.RIGHT:i?f.TOP_LEFT:f.RIGHT},[l,e]),E=r.useMemo(()=>{const i=l==="none"||l==="primary"&&e==="right";return e==="left"?i?f.BOTTOM_LEFT:f.LEFT:i?f.TOP_RIGHT:f.LEFT},[l,e]);return r.useEffect(()=>{const i=setInterval(()=>{const w=u.current,g=c.current,p=m.current;if(!p||!w||!g)return;const s=p.getBoundingClientRect().width,d=w.getBoundingClientRect().width,o=g.getBoundingClientRect().width,{primaryWidth:b,secondaryWidth:R}=e==="left"?{primaryWidth:o,secondaryWidth:d}:{primaryWidth:d,secondaryWidth:o},F=b+2*Y<=s,x=R+b+3*Y<=s;M(F?x?"both":"primary":"none")},33.333333333333336);return()=>clearInterval(i)},[m,u,c,e]),n.jsxs("div",{ref:m,"aria-label":v,style:{position:"relative",width:S,backgroundColor:t.backgroundColor,borderRadius:"5px",color:"white"},children:[n.jsx("div",{ref:c,style:E,children:_}),n.jsx("div",{ref:u,style:C,children:W}),n.jsx(I,{children:O}),n.jsx(I,{children:T})]})},Y=5,y={position:"absolute",transition:"all 200ms cubic-bezier(.47,1.64,.41,.8)",transitionProperty:"transform, top, left, bottom, right"},f={TOP_LEFT:{...y,left:5,top:-5,transform:"translateY(-100%)"},LEFT:{...y,left:5,top:"50%",transform:"translateY(-50%)"},BOTTOM_LEFT:{...y,left:5,bottom:-5,transform:"translateY(100%)"},TOP_RIGHT:{...y,right:5,top:-5,transform:"translateY(-100%)"},RIGHT:{...y,right:5,top:"50%",transform:"translateY(-50%)"},BOTTOM_RIGHT:{...y,right:5,bottom:-5,transform:"translateY(100%)"}},G={whiteSpace:"nowrap",userSelect:"none"},D=({className:t,width:h,gap:e,backgroundColor:S="red",style:v,disabled:T})=>n.jsx("div",{role:"button",className:t,style:{alignSelf:"stretch",borderRadius:"2px",cursor:T?"not-allowed":"ew-resize",...v,width:`${h}px`,margin:`${e}px ${e}px`,background:S}});function H(t){return"touches"in t}const A=t=>H(t)?t.touches[0].clientX:t.clientX,j=(t,h,e)=>Math.min(Math.max(t,h),e),$=({value:t,proportions:h,onChange:e,knobOptions:S,disabled:v,height:T,ariaLabel:P,className:O,style:W,width:_})=>{const m=N(S),u=r.useRef(null),c=t[0]+t[1],l=m.width+m.gap*2,M=r.useRef(c),C=r.useRef(l);M.current=c,C.current=l;const E=r.useRef(!1),i=r.useCallback((s,{width:d,left:o})=>{const b=A(s),R=C.current,F=(b-o-R/2)/(d-R),x=M.current,k=j(x*F,0,x);e==null||e([k,x-k])},[e]),w=r.useCallback(s=>{var b;const d=s.target,o=(b=u.current)==null?void 0:b.getBoundingClientRect();if(u.current&&!u.current.contains(d)||!o||o.width===0){console.log("returning because of rect width",o==null?void 0:o.width);return}return s.preventDefault(),E.current=!0,i(s,o),!0},[i]),g=r.useCallback(s=>{var o;const d=(o=u.current)==null?void 0:o.getBoundingClientRect();return!E.current||!d||d.width===0?!1:(s.preventDefault(),i(s,d),!0)},[i]),p=r.useCallback(s=>E.current?(E.current=!1,s.preventDefault(),!0):!1,[]);return r.useEffect(()=>(window.addEventListener("mousedown",w),window.addEventListener("mousemove",g),window.addEventListener("mouseup",p),window.addEventListener("touchstart",w),window.addEventListener("touchmove",g),window.addEventListener("touchend",p),()=>{window.removeEventListener("mousedown",w),window.removeEventListener("mousemove",g),window.removeEventListener("mouseup",p),window.removeEventListener("touchstart",w),window.removeEventListener("touchmove",g),window.removeEventListener("touchend",p)}),[w,g,p]),n.jsxs("div",{ref:u,role:"slider","aria-label":P,"aria-valuenow":Math.round(t[0]/c*100),style:{display:"flex",flexDirection:"row",height:T,width:_,opacity:v?.6:1,cursor:v?"not-allowed":"pointer",...W},className:O,children:[n.jsx(B,{detail:h[0],valueLabel:`${Math.round(t[0]*100/c)}%`,width:`calc(${t[0]*100/c}% - ${l/2}px)`,primaryNode:"left"}),n.jsx(D,{disabled:v,...m}),n.jsx(B,{detail:h[1],valueLabel:`${Math.round(t[1]*100/c)}%`,width:`calc(${t[1]*100/c}% - ${l/2}px)`,primaryNode:"right"})]})},L={width:5,gap:2,backgroundColor:"red",className:"slider-knob",style:{}};function N(t={}){return{width:t.width??L.width,gap:t.gap??L.gap,backgroundColor:t.backgroundColor??L.backgroundColor,className:t.className??L.className,style:t.style??L.style}}a.ProportionSlider=$,a.default=$,Object.defineProperties(a,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
2
|
+
//# sourceMappingURL=react-proportion-slider.umd.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"react-proportion-slider.umd.js","sources":["../src/components/HiddenSpaceTaker.tsx","../src/components/DynamicChildPositioner.tsx","../src/components/SliderKnob.tsx","../src/utilities/isTouchEvent.tsx","../src/utilities/getClientX.tsx","../src/utilities/maths.ts","../src/ProportionSlider.tsx"],"sourcesContent":["import React from \"react\";\n\ntype HiddenSpaceTakerProps = {\n children: React.ReactNode;\n};\nexport const HiddenSpaceTaker = ({ children }: HiddenSpaceTakerProps) => (\n <span aria-hidden=\"true\" style={{ visibility: \"hidden\" }}>\n {children}\n </span>\n);\n","import React, { useRef, useState, useMemo, useEffect } from \"react\";\nimport { ProportionDetail } from \"./types\";\nimport { HiddenSpaceTaker } from \"./HiddenSpaceTaker\";\n\ntype DynamicChildPositionerProps = {\n detail: ProportionDetail;\n primaryNode: \"left\" | \"right\";\n width: number | string;\n ariaLabel?: string;\n valueLabel: string;\n};\n\nexport const DynamicChildPositioner = ({\n detail,\n valueLabel,\n primaryNode,\n width,\n ariaLabel,\n}: DynamicChildPositionerProps) => {\n const labelNode = <div style={TEXT_STYLE}>{detail.label}</div>;\n const percentNode = <div style={TEXT_STYLE}>{valueLabel}</div>;\n const maxPercentNode = <div style={TEXT_STYLE}>{`100%`}</div>;\n const rightNode = primaryNode === \"right\" ? labelNode : percentNode;\n const leftNode = primaryNode === \"left\" ? labelNode : percentNode;\n const ref = useRef<HTMLDivElement | null>(null);\n const refRight = useRef<HTMLDivElement | null>(null);\n const refLeft = useRef<HTMLDivElement | null>(null);\n const [fitStatus, setFitStatus] = useState<\"both\" | \"primary\" | \"none\">(\n \"both\"\n );\n\n const rightStyle = useMemo(() => {\n const rightNoSpace =\n fitStatus === \"none\" ||\n (fitStatus === \"primary\" && primaryNode === \"left\");\n if (primaryNode === \"right\") {\n return rightNoSpace ? STYLES[\"BOTTOM_RIGHT\"] : STYLES[\"RIGHT\"];\n } else {\n return rightNoSpace ? STYLES[\"TOP_LEFT\"] : STYLES[\"RIGHT\"];\n }\n }, [fitStatus, primaryNode]);\n\n const leftStyle = useMemo(() => {\n const leftNoSpace =\n fitStatus === \"none\" ||\n (fitStatus === \"primary\" && primaryNode === \"right\");\n if (primaryNode === \"left\") {\n return leftNoSpace ? STYLES[\"BOTTOM_LEFT\"] : STYLES[\"LEFT\"];\n } else {\n return leftNoSpace ? STYLES[\"TOP_RIGHT\"] : STYLES[\"LEFT\"];\n }\n }, [fitStatus, primaryNode]);\n\n useEffect(() => {\n const interval = setInterval(() => {\n const textRight = refRight.current;\n const textLeft = refLeft.current;\n const container = ref.current;\n if (!container || !textRight || !textLeft) {\n return;\n }\n const containerRectWidth = container.getBoundingClientRect().width;\n const rightWidth = textRight.getBoundingClientRect().width;\n const leftWidth = textLeft.getBoundingClientRect().width;\n\n const { primaryWidth, secondaryWidth } =\n primaryNode === \"left\"\n ? { primaryWidth: leftWidth, secondaryWidth: rightWidth }\n : { primaryWidth: rightWidth, secondaryWidth: leftWidth };\n\n const primaryCanFit = primaryWidth + 2 * GAP <= containerRectWidth;\n const secondaryCanFit =\n secondaryWidth + primaryWidth + 3 * GAP <= containerRectWidth;\n\n const fitStatus = primaryCanFit\n ? secondaryCanFit\n ? \"both\"\n : \"primary\"\n : \"none\";\n\n setFitStatus(fitStatus);\n }, 1000 / 30);\n return () => clearInterval(interval);\n }, [ref, refRight, refLeft, primaryNode]);\n\n return (\n <div\n ref={ref}\n aria-label={ariaLabel}\n style={{\n position: \"relative\",\n width,\n backgroundColor: detail.backgroundColor,\n borderRadius: \"5px\",\n color: \"white\",\n }}\n >\n <div ref={refLeft} style={leftStyle}>\n {leftNode}\n </div>\n <div ref={refRight} style={rightStyle}>\n {rightNode}\n </div>\n <HiddenSpaceTaker>{maxPercentNode}</HiddenSpaceTaker>\n <HiddenSpaceTaker>{labelNode}</HiddenSpaceTaker>\n </div>\n );\n};\n\nconst GAP = 5;\nconst COMMON_STYLES: React.CSSProperties = {\n position: \"absolute\",\n transition: \"all 200ms cubic-bezier(.47,1.64,.41,.8)\",\n transitionProperty: \"transform, top, left, bottom, right\",\n};\nconst STYLES: Record<string, React.CSSProperties> = {\n TOP_LEFT: {\n ...COMMON_STYLES,\n left: GAP,\n top: -GAP,\n transform: \"translateY(-100%)\",\n },\n LEFT: {\n ...COMMON_STYLES,\n left: GAP,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n },\n BOTTOM_LEFT: {\n ...COMMON_STYLES,\n left: GAP,\n bottom: -GAP,\n transform: \"translateY(100%)\",\n },\n TOP_RIGHT: {\n ...COMMON_STYLES,\n right: GAP,\n top: -GAP,\n transform: \"translateY(-100%)\",\n },\n RIGHT: {\n ...COMMON_STYLES,\n right: GAP,\n top: \"50%\",\n transform: \"translateY(-50%)\",\n },\n BOTTOM_RIGHT: {\n ...COMMON_STYLES,\n right: GAP,\n bottom: -GAP,\n transform: \"translateY(100%)\",\n },\n};\n\nconst TEXT_STYLE = {\n whiteSpace: \"nowrap\",\n userSelect: \"none\",\n} as const;\n","import { CSSProperties } from \"react\";\n\nexport type SliderKnobProps = {\n className?: string;\n width: number;\n gap: number;\n backgroundColor?: string;\n style?: CSSProperties;\n disabled?: boolean;\n};\n\nexport const SliderKnob = ({\n className,\n width,\n gap,\n backgroundColor = \"red\",\n style,\n disabled,\n}: SliderKnobProps) => {\n return (\n <div\n role=\"button\"\n className={className}\n style={{\n alignSelf: \"stretch\",\n borderRadius: \"2px\",\n cursor: disabled ? \"not-allowed\" : \"ew-resize\",\n ...style,\n width: `${width}px`,\n margin: `${gap}px ${gap}px`,\n background: backgroundColor,\n }}\n ></div>\n );\n};\n","export function isTouchEvent(\n e: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent\n): e is TouchEvent | React.TouchEvent {\n return \"touches\" in e;\n}\n","import React from \"react\";\nimport { isTouchEvent } from \"./isTouchEvent\";\n\nexport type EventType =\n | MouseEvent\n | TouchEvent\n | React.MouseEvent\n | React.TouchEvent;\n\nexport const getClientX = (e: EventType): number => {\n return isTouchEvent(e) ? e.touches[0].clientX : e.clientX;\n};\n","export const clamp = (value: number, min: number, max: number) =>\n Math.min(Math.max(value, min), max);\n","import { useCallback, useRef, CSSProperties, useEffect } from \"react\";\nimport {\n DynamicChildPositioner,\n SliderKnob,\n ProportionDetail,\n SliderKnobOptions,\n} from \"./components\";\nimport { EventType, getClientX, clamp } from \"./utilities\";\n\nexport type ProportionSliderProps = {\n /**\n * Current values of the two proportions [left, right]\n * These should be positive numbers\n */\n value: [number, number];\n\n /**\n * Details for the two proportions [left, right]\n */\n proportions: [ProportionDetail, ProportionDetail];\n\n /**\n * Callback when values change\n * @param values The new values [left, right]\n */\n onChange?: (values: [number, number]) => void;\n\n /**\n * Appearance of the slider knob\n */\n knobOptions?: SliderKnobOptions;\n\n /** Height of the slider in pixels */\n height?: number;\n /** Width of the slider in pixels */\n width?: number;\n /** Whether the slider is disabled */\n disabled?: boolean;\n /** Custom class name for the slider container */\n className?: string;\n /** Custom styles for the slider container */\n style?: CSSProperties;\n\n /**\n * Accessibility options\n */\n ariaLabel?: string;\n};\n\nexport const ProportionSlider = ({\n value,\n proportions,\n onChange,\n knobOptions,\n disabled,\n height,\n ariaLabel,\n className,\n style,\n width,\n}: ProportionSliderProps) => {\n const mergedKnobOptions = getMergeKnobOptions(knobOptions);\n\n const ref = useRef<HTMLDivElement | null>(null);\n const total = value[0] + value[1];\n const sliderWidth = mergedKnobOptions.width + mergedKnobOptions.gap * 2;\n const refTotal = useRef<number>(total);\n const refSliderWidth = useRef<number>(sliderWidth);\n refTotal.current = total;\n refSliderWidth.current = sliderWidth;\n const refIsDragging = useRef<boolean>(false);\n\n const onChangeValueFromEvent = useCallback(\n (e: EventType, { width, left }: { width: number; left: number }) => {\n const x = getClientX(e);\n const knobWidth = refSliderWidth.current;\n const factor = (x - left - knobWidth / 2) / (width - knobWidth);\n const total = refTotal.current;\n const value1 = clamp(total * factor, 0, total);\n onChange?.([value1, total - value1]);\n },\n [onChange]\n );\n\n const onDown = useCallback(\n (e: EventType) => {\n const target = e.target as HTMLElement;\n const rect = ref.current?.getBoundingClientRect();\n if (\n (ref.current && !ref.current.contains(target)) ||\n !rect ||\n rect.width === 0\n ) {\n console.log(\"returning because of rect width\", rect?.width);\n return;\n }\n e.preventDefault();\n refIsDragging.current = true;\n onChangeValueFromEvent(e, rect);\n return true;\n },\n [onChangeValueFromEvent]\n );\n\n const onMove = useCallback(\n (e: EventType) => {\n const rect = ref.current?.getBoundingClientRect();\n if (!refIsDragging.current || !rect || rect.width === 0) {\n return false;\n }\n e.preventDefault();\n onChangeValueFromEvent(e, rect);\n return true;\n },\n [onChangeValueFromEvent]\n );\n\n const onUp = useCallback((e: EventType) => {\n if (!refIsDragging.current) return false;\n refIsDragging.current = false;\n e.preventDefault();\n return true;\n }, []);\n\n useEffect(() => {\n window.addEventListener(\"mousedown\", onDown);\n window.addEventListener(\"mousemove\", onMove);\n window.addEventListener(\"mouseup\", onUp);\n window.addEventListener(\"touchstart\", onDown);\n window.addEventListener(\"touchmove\", onMove);\n window.addEventListener(\"touchend\", onUp);\n return () => {\n window.removeEventListener(\"mousedown\", onDown);\n window.removeEventListener(\"mousemove\", onMove);\n window.removeEventListener(\"mouseup\", onUp);\n window.removeEventListener(\"touchstart\", onDown);\n window.removeEventListener(\"touchmove\", onMove);\n window.removeEventListener(\"touchend\", onUp);\n };\n }, [onDown, onMove, onUp]);\n return (\n <div\n ref={ref}\n role=\"slider\"\n aria-label={ariaLabel}\n aria-valuenow={Math.round((value[0] / total) * 100)}\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n height,\n width,\n opacity: disabled ? 0.6 : 1,\n cursor: disabled ? \"not-allowed\" : \"pointer\",\n ...style,\n }}\n className={className}\n >\n <DynamicChildPositioner\n detail={proportions[0]}\n valueLabel={`${Math.round((value[0] * 100) / total)}%`}\n width={`calc(${(value[0] * 100) / total}% - ${sliderWidth / 2}px)`}\n primaryNode=\"left\"\n />\n <SliderKnob disabled={disabled} {...mergedKnobOptions} />\n <DynamicChildPositioner\n detail={proportions[1]}\n valueLabel={`${Math.round((value[1] * 100) / total)}%`}\n width={`calc(${(value[1] * 100) / total}% - ${sliderWidth / 2}px)`}\n primaryNode=\"right\"\n />\n </div>\n );\n};\n\nconst DefaultKnobOptions: Required<SliderKnobOptions> = {\n width: 5,\n gap: 2,\n backgroundColor: \"red\",\n className: \"slider-knob\",\n style: {},\n};\n\nfunction getMergeKnobOptions(\n knobOptions: SliderKnobOptions | undefined = {}\n): Required<SliderKnobOptions> {\n return {\n width: knobOptions.width ?? DefaultKnobOptions.width,\n gap: knobOptions.gap ?? DefaultKnobOptions.gap,\n backgroundColor:\n knobOptions.backgroundColor ?? DefaultKnobOptions.backgroundColor,\n className: knobOptions.className ?? DefaultKnobOptions.className,\n style: knobOptions.style ?? DefaultKnobOptions.style,\n };\n}\n"],"names":["HiddenSpaceTaker","children","jsx","DynamicChildPositioner","detail","valueLabel","primaryNode","width","ariaLabel","labelNode","TEXT_STYLE","percentNode","maxPercentNode","rightNode","leftNode","ref","useRef","refRight","refLeft","fitStatus","setFitStatus","useState","rightStyle","useMemo","rightNoSpace","STYLES","leftStyle","leftNoSpace","useEffect","interval","textRight","textLeft","container","containerRectWidth","rightWidth","leftWidth","primaryWidth","secondaryWidth","primaryCanFit","GAP","secondaryCanFit","jsxs","COMMON_STYLES","SliderKnob","className","gap","backgroundColor","style","disabled","isTouchEvent","e","getClientX","clamp","value","min","max","ProportionSlider","proportions","onChange","knobOptions","height","mergedKnobOptions","getMergeKnobOptions","total","sliderWidth","refTotal","refSliderWidth","refIsDragging","onChangeValueFromEvent","useCallback","left","x","knobWidth","factor","value1","onDown","target","rect","_a","onMove","onUp","DefaultKnobOptions"],"mappings":"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"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function isTouchEvent(e: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent): e is TouchEvent | React.TouchEvent;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const clamp: (value: number, min: number, max: number) => number;
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "react-proportion-slider",
|
3
3
|
"private": false,
|
4
|
-
"version": "0.9.
|
4
|
+
"version": "0.9.5",
|
5
5
|
"type": "module",
|
6
6
|
"files": [
|
7
7
|
"dist"
|
@@ -11,9 +11,9 @@
|
|
11
11
|
"types": "./dist/index.d.ts",
|
12
12
|
"exports": {
|
13
13
|
".": {
|
14
|
+
"types": "./dist/index.d.ts",
|
14
15
|
"import": "./dist/react-proportion-slider.es.js",
|
15
|
-
"require": "./dist/react-proportion-slider.umd.js"
|
16
|
-
"types": "./dist/index.d.ts"
|
16
|
+
"require": "./dist/react-proportion-slider.umd.js"
|
17
17
|
}
|
18
18
|
},
|
19
19
|
"scripts": {
|
@@ -24,10 +24,6 @@
|
|
24
24
|
"test": "vitest",
|
25
25
|
"test:watch": "vitest --watch"
|
26
26
|
},
|
27
|
-
"dependencies": {
|
28
|
-
"react": ">=16.8.0",
|
29
|
-
"react-dom": ">=16.8.0"
|
30
|
-
},
|
31
27
|
"devDependencies": {
|
32
28
|
"@eslint/js": "^9.21.0",
|
33
29
|
"@testing-library/react": "^14.2.1",
|